xref: /llvm-project/llvm/test/CodeGen/AArch64/check-sign-bit-before-extension.ll (revision ee4ba9f3a182397c60e17f14823eb22b2e5831c7)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=aarch64-gnu-linux -o - | FileCheck %s
3
4; These tests make sure that the `cmp` instruction is rendered with an
5; instruction that checks the sign bit of the original unextended data
6; (%in) instead of the sign bit of the sign extended one that is
7; created by the type legalization process.
8;
9; The tests are subdivided in tests that determine the sign bit
10; looking through a `sign_extend_inreg` and tests that determine the
11; sign bit looking through a `sign_extend`.
12
13define i32 @f_i8_sign_extend_inreg(i8 %in, i32 %a, i32 %b) nounwind {
14; CHECK-LABEL: f_i8_sign_extend_inreg:
15; CHECK:       // %bb.0: // %entry
16; CHECK-NEXT:    sxtb w8, w0
17; CHECK-NEXT:    cmp w8, #0
18; CHECK-NEXT:    csel w8, w1, w2, ge
19; CHECK-NEXT:    add w0, w8, w0, uxtb
20; CHECK-NEXT:    ret
21entry:
22  %cmp = icmp sgt i8 %in, -1
23  %ext = zext i8 %in to i32
24  br i1 %cmp, label %A, label %B
25
26A:
27  %retA = add i32 %ext, %a
28  ret i32 %retA
29
30B:
31  %retB = add i32 %ext, %b
32  ret i32 %retB
33}
34
35define i32 @f_i16_sign_extend_inreg(i16 %in, i32 %a, i32 %b) nounwind {
36; CHECK-LABEL: f_i16_sign_extend_inreg:
37; CHECK:       // %bb.0: // %entry
38; CHECK-NEXT:    sxth w8, w0
39; CHECK-NEXT:    cmp w8, #0
40; CHECK-NEXT:    csel w8, w1, w2, ge
41; CHECK-NEXT:    add w0, w8, w0, uxth
42; CHECK-NEXT:    ret
43entry:
44  %cmp = icmp sgt i16 %in, -1
45  %ext = zext i16 %in to i32
46  br i1 %cmp, label %A, label %B
47
48A:
49  %retA = add i32 %ext, %a
50  ret i32 %retA
51
52B:
53  %retB = add i32 %ext, %b
54  ret i32 %retB
55}
56
57define i64 @f_i32_sign_extend_inreg(i32 %in, i64 %a, i64 %b) nounwind {
58; CHECK-LABEL: f_i32_sign_extend_inreg:
59; CHECK:       // %bb.0: // %entry
60; CHECK-NEXT:    cmp w0, #0
61; CHECK-NEXT:    csel x8, x1, x2, ge
62; CHECK-NEXT:    add x0, x8, w0, uxtw
63; CHECK-NEXT:    ret
64entry:
65  %cmp = icmp sgt i32 %in, -1
66  %ext = zext i32 %in to i64
67  br i1 %cmp, label %A, label %B
68
69A:
70  %retA = add i64 %ext, %a
71  ret i64 %retA
72
73B:
74  %retB = add i64 %ext, %b
75  ret i64 %retB
76}
77
78define i32 @g_i8_sign_extend_inreg(i8 %in, i32 %a, i32 %b) nounwind {
79; CHECK-LABEL: g_i8_sign_extend_inreg:
80; CHECK:       // %bb.0: // %entry
81; CHECK-NEXT:    sxtb w8, w0
82; CHECK-NEXT:    cmp w8, #0
83; CHECK-NEXT:    csel w8, w1, w2, lt
84; CHECK-NEXT:    add w0, w8, w0, uxtb
85; CHECK-NEXT:    ret
86entry:
87  %cmp = icmp slt i8 %in, 0
88  %ext = zext i8 %in to i32
89  br i1 %cmp, label %A, label %B
90
91A:
92  %retA = add i32 %ext, %a
93  ret i32 %retA
94
95B:
96  %retB = add i32 %ext, %b
97  ret i32 %retB
98}
99
100define i32 @g_i16_sign_extend_inreg(i16 %in, i32 %a, i32 %b) nounwind {
101; CHECK-LABEL: g_i16_sign_extend_inreg:
102; CHECK:       // %bb.0: // %entry
103; CHECK-NEXT:    sxth w8, w0
104; CHECK-NEXT:    cmp w8, #0
105; CHECK-NEXT:    csel w8, w1, w2, lt
106; CHECK-NEXT:    add w0, w8, w0, uxth
107; CHECK-NEXT:    ret
108entry:
109  %cmp = icmp slt i16 %in, 0
110  %ext = zext i16 %in to i32
111  br i1 %cmp, label %A, label %B
112
113A:
114  %retA = add i32 %ext, %a
115  ret i32 %retA
116
117B:
118  %retB = add i32 %ext, %b
119  ret i32 %retB
120}
121
122define i64 @g_i32_sign_extend_inreg(i32 %in, i64 %a, i64 %b) nounwind {
123; CHECK-LABEL: g_i32_sign_extend_inreg:
124; CHECK:       // %bb.0: // %entry
125; CHECK-NEXT:    cmp w0, #0
126; CHECK-NEXT:    csel x8, x1, x2, lt
127; CHECK-NEXT:    add x0, x8, w0, uxtw
128; CHECK-NEXT:    ret
129entry:
130  %cmp = icmp slt i32 %in, 0
131  %ext = zext i32 %in to i64
132  br i1 %cmp, label %A, label %B
133
134A:
135  %retA = add i64 %ext, %a
136  ret i64 %retA
137
138B:
139  %retB = add i64 %ext, %b
140  ret i64 %retB
141}
142
143define i64 @f_i32_sign_extend_i64(i32 %in, i64 %a, i64 %b) nounwind {
144; CHECK-LABEL: f_i32_sign_extend_i64:
145; CHECK:       // %bb.0: // %entry
146; CHECK-NEXT:    // kill: def $w0 killed $w0 def $x0
147; CHECK-NEXT:    sxtw x8, w0
148; CHECK-NEXT:    cmp x8, #0
149; CHECK-NEXT:    csel x8, x1, x2, ge
150; CHECK-NEXT:    add x0, x8, w0, uxtw
151; CHECK-NEXT:    ret
152entry:
153  %inext = sext i32 %in to i64
154  %cmp = icmp sgt i64 %inext, -1
155  %ext = zext i32 %in to i64
156  br i1 %cmp, label %A, label %B
157
158A:
159  %retA = add i64 %ext, %a
160  ret i64 %retA
161
162B:
163  %retB = add i64 %ext, %b
164  ret i64 %retB
165}
166
167define i64 @g_i32_sign_extend_i64(i32 %in, i64 %a, i64 %b) nounwind {
168; CHECK-LABEL: g_i32_sign_extend_i64:
169; CHECK:       // %bb.0: // %entry
170; CHECK-NEXT:    // kill: def $w0 killed $w0 def $x0
171; CHECK-NEXT:    sxtw x8, w0
172; CHECK-NEXT:    cmp x8, #0
173; CHECK-NEXT:    csel x8, x1, x2, lt
174; CHECK-NEXT:    add x0, x8, w0, uxtw
175; CHECK-NEXT:    ret
176entry:
177  %inext = sext i32 %in to i64
178  %cmp = icmp slt i64 %inext, 0
179  %ext = zext i32 %in to i64
180  br i1 %cmp, label %A, label %B
181
182A:
183  %retA = add i64 %ext, %a
184  ret i64 %retA
185
186B:
187  %retB = add i64 %ext, %b
188  ret i64 %retB
189}
190