1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \ 3; RUN: | FileCheck -check-prefix=RV32I %s 4; RUN: llc -mtriple=riscv32 -mattr=+m -verify-machineinstrs < %s \ 5; RUN: | FileCheck -check-prefix=RV32IM %s 6 7define i32 @square(i32 %a) nounwind { 8; RV32I-LABEL: square: 9; RV32I: # %bb.0: 10; RV32I-NEXT: addi sp, sp, -16 11; RV32I-NEXT: sw ra, 12(sp) 12; RV32I-NEXT: mv a1, a0 13; RV32I-NEXT: call __mulsi3 14; RV32I-NEXT: lw ra, 12(sp) 15; RV32I-NEXT: addi sp, sp, 16 16; RV32I-NEXT: ret 17; 18; RV32IM-LABEL: square: 19; RV32IM: # %bb.0: 20; RV32IM-NEXT: mul a0, a0, a0 21; RV32IM-NEXT: ret 22 %1 = mul i32 %a, %a 23 ret i32 %1 24} 25 26define i32 @mul(i32 %a, i32 %b) nounwind { 27; RV32I-LABEL: mul: 28; RV32I: # %bb.0: 29; RV32I-NEXT: addi sp, sp, -16 30; RV32I-NEXT: sw ra, 12(sp) 31; RV32I-NEXT: call __mulsi3 32; RV32I-NEXT: lw ra, 12(sp) 33; RV32I-NEXT: addi sp, sp, 16 34; RV32I-NEXT: ret 35; 36; RV32IM-LABEL: mul: 37; RV32IM: # %bb.0: 38; RV32IM-NEXT: mul a0, a0, a1 39; RV32IM-NEXT: ret 40 %1 = mul i32 %a, %b 41 ret i32 %1 42} 43 44define i32 @mul_constant(i32 %a) nounwind { 45; RV32I-LABEL: mul_constant: 46; RV32I: # %bb.0: 47; RV32I-NEXT: addi sp, sp, -16 48; RV32I-NEXT: sw ra, 12(sp) 49; RV32I-NEXT: addi a1, zero, 5 50; RV32I-NEXT: call __mulsi3 51; RV32I-NEXT: lw ra, 12(sp) 52; RV32I-NEXT: addi sp, sp, 16 53; RV32I-NEXT: ret 54; 55; RV32IM-LABEL: mul_constant: 56; RV32IM: # %bb.0: 57; RV32IM-NEXT: addi a1, zero, 5 58; RV32IM-NEXT: mul a0, a0, a1 59; RV32IM-NEXT: ret 60 %1 = mul i32 %a, 5 61 ret i32 %1 62} 63 64define i32 @mul_pow2(i32 %a) nounwind { 65; RV32I-LABEL: mul_pow2: 66; RV32I: # %bb.0: 67; RV32I-NEXT: slli a0, a0, 3 68; RV32I-NEXT: ret 69; 70; RV32IM-LABEL: mul_pow2: 71; RV32IM: # %bb.0: 72; RV32IM-NEXT: slli a0, a0, 3 73; RV32IM-NEXT: ret 74 %1 = mul i32 %a, 8 75 ret i32 %1 76} 77 78define i64 @mul64(i64 %a, i64 %b) nounwind { 79; RV32I-LABEL: mul64: 80; RV32I: # %bb.0: 81; RV32I-NEXT: addi sp, sp, -16 82; RV32I-NEXT: sw ra, 12(sp) 83; RV32I-NEXT: call __muldi3 84; RV32I-NEXT: lw ra, 12(sp) 85; RV32I-NEXT: addi sp, sp, 16 86; RV32I-NEXT: ret 87; 88; RV32IM-LABEL: mul64: 89; RV32IM: # %bb.0: 90; RV32IM-NEXT: mul a3, a0, a3 91; RV32IM-NEXT: mulhu a4, a0, a2 92; RV32IM-NEXT: add a3, a4, a3 93; RV32IM-NEXT: mul a1, a1, a2 94; RV32IM-NEXT: add a1, a3, a1 95; RV32IM-NEXT: mul a0, a0, a2 96; RV32IM-NEXT: ret 97 %1 = mul i64 %a, %b 98 ret i64 %1 99} 100 101define i64 @mul64_constant(i64 %a) nounwind { 102; RV32I-LABEL: mul64_constant: 103; RV32I: # %bb.0: 104; RV32I-NEXT: addi sp, sp, -16 105; RV32I-NEXT: sw ra, 12(sp) 106; RV32I-NEXT: addi a2, zero, 5 107; RV32I-NEXT: mv a3, zero 108; RV32I-NEXT: call __muldi3 109; RV32I-NEXT: lw ra, 12(sp) 110; RV32I-NEXT: addi sp, sp, 16 111; RV32I-NEXT: ret 112; 113; RV32IM-LABEL: mul64_constant: 114; RV32IM: # %bb.0: 115; RV32IM-NEXT: addi a2, zero, 5 116; RV32IM-NEXT: mul a1, a1, a2 117; RV32IM-NEXT: mulhu a3, a0, a2 118; RV32IM-NEXT: add a1, a3, a1 119; RV32IM-NEXT: mul a0, a0, a2 120; RV32IM-NEXT: ret 121 %1 = mul i64 %a, 5 122 ret i64 %1 123} 124 125define i32 @mulhs(i32 %a, i32 %b) nounwind { 126; RV32I-LABEL: mulhs: 127; RV32I: # %bb.0: 128; RV32I-NEXT: addi sp, sp, -16 129; RV32I-NEXT: sw ra, 12(sp) 130; RV32I-NEXT: mv a2, a1 131; RV32I-NEXT: srai a1, a0, 31 132; RV32I-NEXT: srai a3, a2, 31 133; RV32I-NEXT: call __muldi3 134; RV32I-NEXT: mv a0, a1 135; RV32I-NEXT: lw ra, 12(sp) 136; RV32I-NEXT: addi sp, sp, 16 137; RV32I-NEXT: ret 138; 139; RV32IM-LABEL: mulhs: 140; RV32IM: # %bb.0: 141; RV32IM-NEXT: mulh a0, a0, a1 142; RV32IM-NEXT: ret 143 %1 = sext i32 %a to i64 144 %2 = sext i32 %b to i64 145 %3 = mul i64 %1, %2 146 %4 = lshr i64 %3, 32 147 %5 = trunc i64 %4 to i32 148 ret i32 %5 149} 150 151define i32 @mulhu(i32 %a, i32 %b) nounwind { 152; RV32I-LABEL: mulhu: 153; RV32I: # %bb.0: 154; RV32I-NEXT: addi sp, sp, -16 155; RV32I-NEXT: sw ra, 12(sp) 156; RV32I-NEXT: mv a2, a1 157; RV32I-NEXT: mv a1, zero 158; RV32I-NEXT: mv a3, zero 159; RV32I-NEXT: call __muldi3 160; RV32I-NEXT: mv a0, a1 161; RV32I-NEXT: lw ra, 12(sp) 162; RV32I-NEXT: addi sp, sp, 16 163; RV32I-NEXT: ret 164; 165; RV32IM-LABEL: mulhu: 166; RV32IM: # %bb.0: 167; RV32IM-NEXT: mulhu a0, a0, a1 168; RV32IM-NEXT: ret 169 %1 = zext i32 %a to i64 170 %2 = zext i32 %b to i64 171 %3 = mul i64 %1, %2 172 %4 = lshr i64 %3, 32 173 %5 = trunc i64 %4 to i32 174 ret i32 %5 175} 176