xref: /llvm-project/llvm/test/CodeGen/RISCV/add-imm.ll (revision 9122c5235ec85ce0c0ad337e862b006e7b349d84)
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=riscv64 -verify-machineinstrs < %s \
5; RUN:   | FileCheck -check-prefix=RV64I %s
6
7; These test how the immediate in an addition is materialized.
8
9define i32 @add_positive_low_bound_reject(i32 %a) nounwind {
10; RV32I-LABEL: add_positive_low_bound_reject:
11; RV32I:       # %bb.0:
12; RV32I-NEXT:    addi a0, a0, 2047
13; RV32I-NEXT:    ret
14;
15; RV64I-LABEL: add_positive_low_bound_reject:
16; RV64I:       # %bb.0:
17; RV64I-NEXT:    addiw a0, a0, 2047
18; RV64I-NEXT:    ret
19  %1 = add i32 %a, 2047
20  ret i32 %1
21}
22
23define i32 @add_positive_low_bound_accept(i32 %a) nounwind {
24; RV32I-LABEL: add_positive_low_bound_accept:
25; RV32I:       # %bb.0:
26; RV32I-NEXT:    addi a0, a0, 2047
27; RV32I-NEXT:    addi a0, a0, 1
28; RV32I-NEXT:    ret
29;
30; RV64I-LABEL: add_positive_low_bound_accept:
31; RV64I:       # %bb.0:
32; RV64I-NEXT:    addi a0, a0, 2047
33; RV64I-NEXT:    addiw a0, a0, 1
34; RV64I-NEXT:    ret
35  %1 = add i32 %a, 2048
36  ret i32 %1
37}
38
39define i32 @add_positive_high_bound_accept(i32 %a) nounwind {
40; RV32I-LABEL: add_positive_high_bound_accept:
41; RV32I:       # %bb.0:
42; RV32I-NEXT:    addi a0, a0, 2047
43; RV32I-NEXT:    addi a0, a0, 2047
44; RV32I-NEXT:    ret
45;
46; RV64I-LABEL: add_positive_high_bound_accept:
47; RV64I:       # %bb.0:
48; RV64I-NEXT:    addi a0, a0, 2047
49; RV64I-NEXT:    addiw a0, a0, 2047
50; RV64I-NEXT:    ret
51  %1 = add i32 %a, 4094
52  ret i32 %1
53}
54
55define i32 @add_positive_high_bound_reject(i32 %a) nounwind {
56; RV32I-LABEL: add_positive_high_bound_reject:
57; RV32I:       # %bb.0:
58; RV32I-NEXT:    lui a1, 1
59; RV32I-NEXT:    addi a1, a1, -1
60; RV32I-NEXT:    add a0, a0, a1
61; RV32I-NEXT:    ret
62;
63; RV64I-LABEL: add_positive_high_bound_reject:
64; RV64I:       # %bb.0:
65; RV64I-NEXT:    lui a1, 1
66; RV64I-NEXT:    addi a1, a1, -1
67; RV64I-NEXT:    addw a0, a0, a1
68; RV64I-NEXT:    ret
69  %1 = add i32 %a, 4095
70  ret i32 %1
71}
72
73define i32 @add_negative_high_bound_reject(i32 %a) nounwind {
74; RV32I-LABEL: add_negative_high_bound_reject:
75; RV32I:       # %bb.0:
76; RV32I-NEXT:    addi a0, a0, -2048
77; RV32I-NEXT:    ret
78;
79; RV64I-LABEL: add_negative_high_bound_reject:
80; RV64I:       # %bb.0:
81; RV64I-NEXT:    addiw a0, a0, -2048
82; RV64I-NEXT:    ret
83  %1 = add i32 %a, -2048
84  ret i32 %1
85}
86
87define i32 @add_negative_high_bound_accept(i32 %a) nounwind {
88; RV32I-LABEL: add_negative_high_bound_accept:
89; RV32I:       # %bb.0:
90; RV32I-NEXT:    addi a0, a0, -2048
91; RV32I-NEXT:    addi a0, a0, -1
92; RV32I-NEXT:    ret
93;
94; RV64I-LABEL: add_negative_high_bound_accept:
95; RV64I:       # %bb.0:
96; RV64I-NEXT:    addi a0, a0, -2048
97; RV64I-NEXT:    addiw a0, a0, -1
98; RV64I-NEXT:    ret
99  %1 = add i32 %a, -2049
100  ret i32 %1
101}
102
103define i32 @add_negative_low_bound_accept(i32 %a) nounwind {
104; RV32I-LABEL: add_negative_low_bound_accept:
105; RV32I:       # %bb.0:
106; RV32I-NEXT:    addi a0, a0, -2048
107; RV32I-NEXT:    addi a0, a0, -2048
108; RV32I-NEXT:    ret
109;
110; RV64I-LABEL: add_negative_low_bound_accept:
111; RV64I:       # %bb.0:
112; RV64I-NEXT:    addi a0, a0, -2048
113; RV64I-NEXT:    addiw a0, a0, -2048
114; RV64I-NEXT:    ret
115  %1 = add i32 %a, -4096
116  ret i32 %1
117}
118
119define i32 @add_negative_low_bound_reject(i32 %a) nounwind {
120; RV32I-LABEL: add_negative_low_bound_reject:
121; RV32I:       # %bb.0:
122; RV32I-NEXT:    lui a1, 1048575
123; RV32I-NEXT:    addi a1, a1, -1
124; RV32I-NEXT:    add a0, a0, a1
125; RV32I-NEXT:    ret
126;
127; RV64I-LABEL: add_negative_low_bound_reject:
128; RV64I:       # %bb.0:
129; RV64I-NEXT:    lui a1, 1048575
130; RV64I-NEXT:    addi a1, a1, -1
131; RV64I-NEXT:    addw a0, a0, a1
132; RV64I-NEXT:    ret
133  %1 = add i32 %a, -4097
134  ret i32 %1
135}
136
137define i32 @add32_accept(i32 %a) nounwind {
138; RV32I-LABEL: add32_accept:
139; RV32I:       # %bb.0:
140; RV32I-NEXT:    addi a0, a0, 2047
141; RV32I-NEXT:    addi a0, a0, 952
142; RV32I-NEXT:    ret
143;
144; RV64I-LABEL: add32_accept:
145; RV64I:       # %bb.0:
146; RV64I-NEXT:    addi a0, a0, 2047
147; RV64I-NEXT:    addiw a0, a0, 952
148; RV64I-NEXT:    ret
149  %1 = add i32 %a, 2999
150  ret i32 %1
151}
152
153define signext i32 @add32_sext_accept(i32 signext %a) nounwind {
154; RV32I-LABEL: add32_sext_accept:
155; RV32I:       # %bb.0:
156; RV32I-NEXT:    addi a0, a0, 2047
157; RV32I-NEXT:    addi a0, a0, 952
158; RV32I-NEXT:    ret
159;
160; RV64I-LABEL: add32_sext_accept:
161; RV64I:       # %bb.0:
162; RV64I-NEXT:    addi a0, a0, 2047
163; RV64I-NEXT:    addiw a0, a0, 952
164; RV64I-NEXT:    ret
165  %1 = add i32 %a, 2999
166  ret i32 %1
167}
168
169@gv0 = global i32 0, align 4
170define signext i32 @add32_sext_reject_on_rv64(i32 signext %a) nounwind {
171; RV32I-LABEL: add32_sext_reject_on_rv64:
172; RV32I:       # %bb.0:
173; RV32I-NEXT:    addi a0, a0, 2047
174; RV32I-NEXT:    addi a0, a0, 953
175; RV32I-NEXT:    lui a1, %hi(gv0)
176; RV32I-NEXT:    sw a0, %lo(gv0)(a1)
177; RV32I-NEXT:    ret
178;
179; RV64I-LABEL: add32_sext_reject_on_rv64:
180; RV64I:       # %bb.0:
181; RV64I-NEXT:    addi a0, a0, 2047
182; RV64I-NEXT:    addiw a0, a0, 953
183; RV64I-NEXT:    lui a1, %hi(gv0)
184; RV64I-NEXT:    sw a0, %lo(gv0)(a1)
185; RV64I-NEXT:    ret
186  %b = add nsw i32 %a, 3000
187  store i32 %b, ptr @gv0, align 4
188  ret i32 %b
189}
190
191define i64 @add64_accept(i64 %a) nounwind {
192; RV32I-LABEL: add64_accept:
193; RV32I:       # %bb.0:
194; RV32I-NEXT:    addi a2, a0, 2047
195; RV32I-NEXT:    addi a2, a2, 952
196; RV32I-NEXT:    sltu a0, a2, a0
197; RV32I-NEXT:    add a1, a1, a0
198; RV32I-NEXT:    mv a0, a2
199; RV32I-NEXT:    ret
200;
201; RV64I-LABEL: add64_accept:
202; RV64I:       # %bb.0:
203; RV64I-NEXT:    addi a0, a0, 2047
204; RV64I-NEXT:    addi a0, a0, 952
205; RV64I-NEXT:    ret
206  %1 = add i64 %a, 2999
207  ret i64 %1
208}
209
210@ga = global i32 0, align 4
211@gb = global i32 0, align 4
212define void @add32_reject() nounwind {
213; RV32I-LABEL: add32_reject:
214; RV32I:       # %bb.0:
215; RV32I-NEXT:    lui a0, %hi(ga)
216; RV32I-NEXT:    lui a1, %hi(gb)
217; RV32I-NEXT:    lw a2, %lo(ga)(a0)
218; RV32I-NEXT:    lw a3, %lo(gb)(a1)
219; RV32I-NEXT:    lui a4, 1
220; RV32I-NEXT:    addi a4, a4, -1096
221; RV32I-NEXT:    add a2, a2, a4
222; RV32I-NEXT:    add a3, a3, a4
223; RV32I-NEXT:    sw a2, %lo(ga)(a0)
224; RV32I-NEXT:    sw a3, %lo(gb)(a1)
225; RV32I-NEXT:    ret
226;
227; RV64I-LABEL: add32_reject:
228; RV64I:       # %bb.0:
229; RV64I-NEXT:    lui a0, %hi(ga)
230; RV64I-NEXT:    lui a1, %hi(gb)
231; RV64I-NEXT:    lw a2, %lo(ga)(a0)
232; RV64I-NEXT:    lw a3, %lo(gb)(a1)
233; RV64I-NEXT:    lui a4, 1
234; RV64I-NEXT:    addi a4, a4, -1096
235; RV64I-NEXT:    add a2, a2, a4
236; RV64I-NEXT:    add a3, a3, a4
237; RV64I-NEXT:    sw a2, %lo(ga)(a0)
238; RV64I-NEXT:    sw a3, %lo(gb)(a1)
239; RV64I-NEXT:    ret
240  %1 = load i32, ptr @ga, align 4
241  %2 = load i32, ptr @gb, align 4
242  %3 = add i32 %1, 3000
243  %4 = add i32 %2, 3000
244  store i32 %3, ptr @ga, align 4
245  store i32 %4, ptr @gb, align 4
246  ret void
247}
248