[NFC][RemoveDIs] Prefer iterators over inst-pointers in InstCombine
[llvm-project.git] / llvm / test / CodeGen / AArch64 / check-sign-bit-before-extension.ll
blob8fbed8bfdb3fd86b7c3eadd1b2f90b05ac2041b3
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=aarch64-gnu-linux -o - | FileCheck %s
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.
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`.
13 define 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
21 entry:
22   %cmp = icmp sgt i8 %in, -1
23   %ext = zext i8 %in to i32
24   br i1 %cmp, label %A, label %B
27   %retA = add i32 %ext, %a
28   ret i32 %retA
31   %retB = add i32 %ext, %b
32   ret i32 %retB
35 define 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
43 entry:
44   %cmp = icmp sgt i16 %in, -1
45   %ext = zext i16 %in to i32
46   br i1 %cmp, label %A, label %B
49   %retA = add i32 %ext, %a
50   ret i32 %retA
53   %retB = add i32 %ext, %b
54   ret i32 %retB
57 define 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
64 entry:
65   %cmp = icmp sgt i32 %in, -1
66   %ext = zext i32 %in to i64
67   br i1 %cmp, label %A, label %B
70   %retA = add i64 %ext, %a
71   ret i64 %retA
74   %retB = add i64 %ext, %b
75   ret i64 %retB
78 define 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
86 entry:
87   %cmp = icmp slt i8 %in, 0
88   %ext = zext i8 %in to i32
89   br i1 %cmp, label %A, label %B
92   %retA = add i32 %ext, %a
93   ret i32 %retA
96   %retB = add i32 %ext, %b
97   ret i32 %retB
100 define 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
108 entry:
109   %cmp = icmp slt i16 %in, 0
110   %ext = zext i16 %in to i32
111   br i1 %cmp, label %A, label %B
114   %retA = add i32 %ext, %a
115   ret i32 %retA
118   %retB = add i32 %ext, %b
119   ret i32 %retB
122 define 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
129 entry:
130   %cmp = icmp slt i32 %in, 0
131   %ext = zext i32 %in to i64
132   br i1 %cmp, label %A, label %B
135   %retA = add i64 %ext, %a
136   ret i64 %retA
139   %retB = add i64 %ext, %b
140   ret i64 %retB
143 define 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
152 entry:
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
159   %retA = add i64 %ext, %a
160   ret i64 %retA
163   %retB = add i64 %ext, %b
164   ret i64 %retB
167 define 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
176 entry:
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
183   %retA = add i64 %ext, %a
184   ret i64 %retA
187   %retB = add i64 %ext, %b
188   ret i64 %retB