xref: /llvm-project/llvm/test/CodeGen/X86/fold-add.ll (revision 570871eab530524e98781238a48897a881834211)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=x86_64 -relocation-model=static < %s | FileCheck --check-prefixes=STATIC %s
3; RUN: llc -mtriple=x86_64 -relocation-model=pic < %s | FileCheck --check-prefixes=PIC %s
4; RUN: llc -mtriple=x86_64 -code-model=medium -relocation-model=static < %s | FileCheck --check-prefixes=MSTATIC %s
5; RUN: llc -mtriple=x86_64 -code-model=medium -relocation-model=pic < %s | FileCheck --check-prefixes=MPIC %s
6
7@foo = internal global i32 0
8
9define dso_local i64 @zero() #0 {
10; STATIC-LABEL: zero:
11; STATIC:       # %bb.0: # %entry
12; STATIC-NEXT:    movl $foo, %eax
13; STATIC-NEXT:    retq
14;
15; PIC-LABEL: zero:
16; PIC:       # %bb.0: # %entry
17; PIC-NEXT:    leaq foo(%rip), %rax
18; PIC-NEXT:    retq
19;
20; MSTATIC-LABEL: zero:
21; MSTATIC:       # %bb.0: # %entry
22; MSTATIC-NEXT:    movabsq $foo, %rax
23; MSTATIC-NEXT:    retq
24;
25; MPIC-LABEL: zero:
26; MPIC:       # %bb.0: # %entry
27; MPIC-NEXT:    leaq _GLOBAL_OFFSET_TABLE_(%rip), %rcx
28; MPIC-NEXT:    movabsq $foo@GOTOFF, %rax
29; MPIC-NEXT:    addq %rcx, %rax
30; MPIC-NEXT:    retq
31entry:
32  ret i64 add (i64 ptrtoint (ptr @foo to i64), i64 0)
33}
34
35define dso_local i64 @one() #0 {
36; STATIC-LABEL: one:
37; STATIC:       # %bb.0: # %entry
38; STATIC-NEXT:    movl $foo+1, %eax
39; STATIC-NEXT:    retq
40;
41; PIC-LABEL: one:
42; PIC:       # %bb.0: # %entry
43; PIC-NEXT:    leaq foo+1(%rip), %rax
44; PIC-NEXT:    retq
45;
46; MSTATIC-LABEL: one:
47; MSTATIC:       # %bb.0: # %entry
48; MSTATIC-NEXT:    movabsq $foo+1, %rax
49; MSTATIC-NEXT:    retq
50;
51; MPIC-LABEL: one:
52; MPIC:       # %bb.0: # %entry
53; MPIC-NEXT:    leaq _GLOBAL_OFFSET_TABLE_(%rip), %rax
54; MPIC-NEXT:    movabsq $foo@GOTOFF, %rcx
55; MPIC-NEXT:    leaq 1(%rax,%rcx), %rax
56; MPIC-NEXT:    retq
57entry:
58  ret i64 add (i64 ptrtoint (ptr @foo to i64), i64 1)
59}
60
61;; Check we don't fold a large offset into leaq, otherwise
62;; the large r_addend can easily cause a relocation overflow.
63define dso_local i64 @large() #0 {
64; STATIC-LABEL: large:
65; STATIC:       # %bb.0: # %entry
66; STATIC-NEXT:    movl $1701208431, %eax # imm = 0x6566616F
67; STATIC-NEXT:    leaq foo(%rax), %rax
68; STATIC-NEXT:    retq
69;
70; PIC-LABEL: large:
71; PIC:       # %bb.0: # %entry
72; PIC-NEXT:    leaq foo(%rip), %rax
73; PIC-NEXT:    addq $1701208431, %rax # imm = 0x6566616F
74; PIC-NEXT:    retq
75;
76; MSTATIC-LABEL: large:
77; MSTATIC:       # %bb.0: # %entry
78; MSTATIC-NEXT:    movabsq $foo, %rax
79; MSTATIC-NEXT:    addq $1701208431, %rax # imm = 0x6566616F
80; MSTATIC-NEXT:    retq
81;
82; MPIC-LABEL: large:
83; MPIC:       # %bb.0: # %entry
84; MPIC-NEXT:    leaq _GLOBAL_OFFSET_TABLE_(%rip), %rax
85; MPIC-NEXT:    movabsq $foo@GOTOFF, %rcx
86; MPIC-NEXT:    leaq 1701208431(%rax,%rcx), %rax
87; MPIC-NEXT:    retq
88entry:
89  ret i64 add (i64 ptrtoint (ptr @foo to i64), i64 1701208431)
90}
91
92;; Test we don't emit movl foo-1, %eax. ELF R_X86_64_32 does not allow
93;; a negative value.
94define dso_local i64 @neg_1() #0 {
95; STATIC-LABEL: neg_1:
96; STATIC:       # %bb.0: # %entry
97; STATIC-NEXT:    leaq foo-1(%rip), %rax
98; STATIC-NEXT:    retq
99;
100; PIC-LABEL: neg_1:
101; PIC:       # %bb.0: # %entry
102; PIC-NEXT:    leaq foo-1(%rip), %rax
103; PIC-NEXT:    retq
104;
105; MSTATIC-LABEL: neg_1:
106; MSTATIC:       # %bb.0: # %entry
107; MSTATIC-NEXT:    movabsq $foo, %rax
108; MSTATIC-NEXT:    decq %rax
109; MSTATIC-NEXT:    retq
110;
111; MPIC-LABEL: neg_1:
112; MPIC:       # %bb.0: # %entry
113; MPIC-NEXT:    leaq _GLOBAL_OFFSET_TABLE_(%rip), %rax
114; MPIC-NEXT:    movabsq $foo@GOTOFF, %rcx
115; MPIC-NEXT:    leaq -1(%rax,%rcx), %rax
116; MPIC-NEXT:    retq
117entry:
118  ret i64 add (i64 ptrtoint (ptr @foo to i64), i64 -1)
119}
120
121;; Test we don't emit movl foo-2147483648, %eax. ELF R_X86_64_32 does not allow
122;; a negative value.
123define dso_local i64 @neg_0x80000000() #0 {
124; STATIC-LABEL: neg_0x80000000:
125; STATIC:       # %bb.0: # %entry
126; STATIC-NEXT:    leaq foo-2147483648(%rip), %rax
127; STATIC-NEXT:    retq
128;
129; PIC-LABEL: neg_0x80000000:
130; PIC:       # %bb.0: # %entry
131; PIC-NEXT:    leaq foo-2147483648(%rip), %rax
132; PIC-NEXT:    retq
133;
134; MSTATIC-LABEL: neg_0x80000000:
135; MSTATIC:       # %bb.0: # %entry
136; MSTATIC-NEXT:    movabsq $foo, %rax
137; MSTATIC-NEXT:    addq $-2147483648, %rax # imm = 0x80000000
138; MSTATIC-NEXT:    retq
139;
140; MPIC-LABEL: neg_0x80000000:
141; MPIC:       # %bb.0: # %entry
142; MPIC-NEXT:    leaq _GLOBAL_OFFSET_TABLE_(%rip), %rax
143; MPIC-NEXT:    movabsq $foo@GOTOFF, %rcx
144; MPIC-NEXT:    leaq -2147483648(%rax,%rcx), %rax
145; MPIC-NEXT:    retq
146entry:
147  ret i64 add (i64 ptrtoint (ptr @foo to i64), i64 -2147483648)
148}
149
150define dso_local i64 @neg_0x80000001() #0 {
151; STATIC-LABEL: neg_0x80000001:
152; STATIC:       # %bb.0: # %entry
153; STATIC-NEXT:    movabsq $-2147483649, %rax # imm = 0xFFFFFFFF7FFFFFFF
154; STATIC-NEXT:    leaq foo(%rax), %rax
155; STATIC-NEXT:    retq
156;
157; PIC-LABEL: neg_0x80000001:
158; PIC:       # %bb.0: # %entry
159; PIC-NEXT:    leaq foo(%rip), %rcx
160; PIC-NEXT:    movabsq $-2147483649, %rax # imm = 0xFFFFFFFF7FFFFFFF
161; PIC-NEXT:    addq %rcx, %rax
162; PIC-NEXT:    retq
163;
164; MSTATIC-LABEL: neg_0x80000001:
165; MSTATIC:       # %bb.0: # %entry
166; MSTATIC-NEXT:    movabsq $-2147483649, %rcx # imm = 0xFFFFFFFF7FFFFFFF
167; MSTATIC-NEXT:    movabsq $foo, %rax
168; MSTATIC-NEXT:    addq %rcx, %rax
169; MSTATIC-NEXT:    retq
170;
171; MPIC-LABEL: neg_0x80000001:
172; MPIC:       # %bb.0: # %entry
173; MPIC-NEXT:    leaq _GLOBAL_OFFSET_TABLE_(%rip), %rax
174; MPIC-NEXT:    movabsq $foo@GOTOFF, %rcx
175; MPIC-NEXT:    addq %rax, %rcx
176; MPIC-NEXT:    movabsq $-2147483649, %rax # imm = 0xFFFFFFFF7FFFFFFF
177; MPIC-NEXT:    addq %rcx, %rax
178; MPIC-NEXT:    retq
179entry:
180  ret i64 add (i64 ptrtoint (ptr @foo to i64), i64 -2147483649)
181}
182
183define internal void @bar() #0 {
184; STATIC-LABEL: bar:
185; STATIC:       # %bb.0:
186; STATIC-NEXT:    retq
187;
188; PIC-LABEL: bar:
189; PIC:       # %bb.0:
190; PIC-NEXT:    retq
191;
192; MSTATIC-LABEL: bar:
193; MSTATIC:       # %bb.0:
194; MSTATIC-NEXT:    retq
195;
196; MPIC-LABEL: bar:
197; MPIC:       # %bb.0:
198; MPIC-NEXT:    retq
199  ret void
200}
201
202define dso_local i64 @fun_neg_0xfeffffff() #0 {
203; STATIC-LABEL: fun_neg_0xfeffffff:
204; STATIC:       # %bb.0:
205; STATIC-NEXT:    movl $bar, %eax
206; STATIC-NEXT:    addq $-16777217, %rax # imm = 0xFEFFFFFF
207; STATIC-NEXT:    retq
208;
209; PIC-LABEL: fun_neg_0xfeffffff:
210; PIC:       # %bb.0:
211; PIC-NEXT:    leaq bar-16777217(%rip), %rax
212; PIC-NEXT:    retq
213;
214; MSTATIC-LABEL: fun_neg_0xfeffffff:
215; MSTATIC:       # %bb.0:
216; MSTATIC-NEXT:    movl $bar, %eax
217; MSTATIC-NEXT:    addq $-16777217, %rax # imm = 0xFEFFFFFF
218; MSTATIC-NEXT:    retq
219;
220; MPIC-LABEL: fun_neg_0xfeffffff:
221; MPIC:       # %bb.0:
222; MPIC-NEXT:    leaq bar-16777217(%rip), %rax
223; MPIC-NEXT:    retq
224  ret i64 add (i64 ptrtoint (ptr @bar to i64), i64 -16777217)
225}
226
227define dso_local i64 @fun_neg_ff000000() #0 {
228; STATIC-LABEL: fun_neg_ff000000:
229; STATIC:       # %bb.0:
230; STATIC-NEXT:    leaq bar-16777216(%rip), %rax
231; STATIC-NEXT:    retq
232;
233; PIC-LABEL: fun_neg_ff000000:
234; PIC:       # %bb.0:
235; PIC-NEXT:    leaq bar-16777216(%rip), %rax
236; PIC-NEXT:    retq
237;
238; MSTATIC-LABEL: fun_neg_ff000000:
239; MSTATIC:       # %bb.0:
240; MSTATIC-NEXT:    leaq bar-16777216(%rip), %rax
241; MSTATIC-NEXT:    retq
242;
243; MPIC-LABEL: fun_neg_ff000000:
244; MPIC:       # %bb.0:
245; MPIC-NEXT:    leaq bar-16777216(%rip), %rax
246; MPIC-NEXT:    retq
247  ret i64 add (i64 ptrtoint (ptr @bar to i64), i64 -16777216)
248}
249
250attributes #0 = { nounwind }
251