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