1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=aarch64-- | FileCheck %s
4 ; CodeGenPrepare is expected to form overflow intrinsics to improve DAG/isel.
6 define i1 @usubo_ult_i64(i64 %x, i64 %y, ptr %p) nounwind {
7 ; CHECK-LABEL: usubo_ult_i64:
9 ; CHECK-NEXT: subs x8, x0, x1
10 ; CHECK-NEXT: cset w0, lo
11 ; CHECK-NEXT: str x8, [x2]
15 %ov = icmp ult i64 %x, %y
19 ; Verify insertion point for single-BB. Toggle predicate.
21 define i1 @usubo_ugt_i32(i32 %x, i32 %y, ptr %p) nounwind {
22 ; CHECK-LABEL: usubo_ugt_i32:
24 ; CHECK-NEXT: subs w8, w0, w1
25 ; CHECK-NEXT: cset w0, lo
26 ; CHECK-NEXT: str w8, [x2]
28 %ov = icmp ugt i32 %y, %x
34 ; Constant operand should match.
36 define i1 @usubo_ugt_constant_op0_i8(i8 %x, ptr %p) nounwind {
37 ; CHECK-LABEL: usubo_ugt_constant_op0_i8:
39 ; CHECK-NEXT: and w8, w0, #0xff
40 ; CHECK-NEXT: mov w9, #42 // =0x2a
41 ; CHECK-NEXT: cmp w8, #42
42 ; CHECK-NEXT: sub w9, w9, w0
43 ; CHECK-NEXT: cset w8, hi
44 ; CHECK-NEXT: strb w9, [x1]
45 ; CHECK-NEXT: mov w0, w8
48 %ov = icmp ugt i8 %x, 42
53 ; Compare with constant operand 0 is canonicalized by commuting, but verify match for non-canonical form.
55 define i1 @usubo_ult_constant_op0_i16(i16 %x, ptr %p) nounwind {
56 ; CHECK-LABEL: usubo_ult_constant_op0_i16:
58 ; CHECK-NEXT: and w8, w0, #0xffff
59 ; CHECK-NEXT: mov w9, #43 // =0x2b
60 ; CHECK-NEXT: cmp w8, #43
61 ; CHECK-NEXT: sub w9, w9, w0
62 ; CHECK-NEXT: cset w8, hi
63 ; CHECK-NEXT: strh w9, [x1]
64 ; CHECK-NEXT: mov w0, w8
67 %ov = icmp ult i16 43, %x
72 ; Subtract with constant operand 1 is canonicalized to add.
74 define i1 @usubo_ult_constant_op1_i16(i16 %x, ptr %p) nounwind {
75 ; CHECK-LABEL: usubo_ult_constant_op1_i16:
77 ; CHECK-NEXT: and w8, w0, #0xffff
78 ; CHECK-NEXT: sub w9, w0, #44
79 ; CHECK-NEXT: cmp w8, #44
80 ; CHECK-NEXT: strh w9, [x1]
81 ; CHECK-NEXT: cset w8, lo
82 ; CHECK-NEXT: mov w0, w8
85 %ov = icmp ult i16 %x, 44
90 define i1 @usubo_ugt_constant_op1_i8(i8 %x, ptr %p) nounwind {
91 ; CHECK-LABEL: usubo_ugt_constant_op1_i8:
93 ; CHECK-NEXT: and w8, w0, #0xff
94 ; CHECK-NEXT: sub w9, w0, #45
95 ; CHECK-NEXT: cmp w8, #45
96 ; CHECK-NEXT: strb w9, [x1]
97 ; CHECK-NEXT: cset w8, lo
98 ; CHECK-NEXT: mov w0, w8
100 %ov = icmp ugt i8 45, %x
106 ; Special-case: subtract 1 changes the compare predicate and constant.
108 define i1 @usubo_eq_constant1_op1_i32(i32 %x, ptr %p) nounwind {
109 ; CHECK-LABEL: usubo_eq_constant1_op1_i32:
111 ; CHECK-NEXT: cmp w0, #0
112 ; CHECK-NEXT: sub w9, w0, #1
113 ; CHECK-NEXT: cset w8, eq
114 ; CHECK-NEXT: str w9, [x1]
115 ; CHECK-NEXT: mov w0, w8
118 %ov = icmp eq i32 %x, 0
123 ; Verify insertion point for multi-BB.
125 declare void @call(i1)
127 define i1 @usubo_ult_sub_dominates_i64(i64 %x, i64 %y, ptr %p, i1 %cond) nounwind {
128 ; CHECK-LABEL: usubo_ult_sub_dominates_i64:
129 ; CHECK: // %bb.0: // %entry
130 ; CHECK-NEXT: tbz w3, #0, .LBB7_2
131 ; CHECK-NEXT: // %bb.1: // %t
132 ; CHECK-NEXT: subs x8, x0, x1
133 ; CHECK-NEXT: cset w3, lo
134 ; CHECK-NEXT: str x8, [x2]
135 ; CHECK-NEXT: .LBB7_2: // %common.ret
136 ; CHECK-NEXT: and w0, w3, #0x1
139 br i1 %cond, label %t, label %f
144 br i1 %cond, label %end, label %f
150 %ov = icmp ult i64 %x, %y
154 define i1 @usubo_ult_cmp_dominates_i64(i64 %x, i64 %y, ptr %p, i1 %cond) nounwind {
155 ; CHECK-LABEL: usubo_ult_cmp_dominates_i64:
156 ; CHECK: // %bb.0: // %entry
157 ; CHECK-NEXT: stp x30, x23, [sp, #-48]! // 16-byte Folded Spill
158 ; CHECK-NEXT: stp x20, x19, [sp, #32] // 16-byte Folded Spill
159 ; CHECK-NEXT: mov w19, w3
160 ; CHECK-NEXT: stp x22, x21, [sp, #16] // 16-byte Folded Spill
161 ; CHECK-NEXT: tbz w3, #0, .LBB8_3
162 ; CHECK-NEXT: // %bb.1: // %t
163 ; CHECK-NEXT: cmp x0, x1
164 ; CHECK-NEXT: mov x23, x0
165 ; CHECK-NEXT: mov x20, x2
166 ; CHECK-NEXT: cset w21, lo
167 ; CHECK-NEXT: mov x22, x1
168 ; CHECK-NEXT: mov w0, w21
169 ; CHECK-NEXT: bl call
170 ; CHECK-NEXT: subs x8, x23, x22
171 ; CHECK-NEXT: b.hs .LBB8_3
172 ; CHECK-NEXT: // %bb.2: // %end
173 ; CHECK-NEXT: mov w19, w21
174 ; CHECK-NEXT: str x8, [x20]
175 ; CHECK-NEXT: .LBB8_3: // %common.ret
176 ; CHECK-NEXT: and w0, w19, #0x1
177 ; CHECK-NEXT: ldp x20, x19, [sp, #32] // 16-byte Folded Reload
178 ; CHECK-NEXT: ldp x22, x21, [sp, #16] // 16-byte Folded Reload
179 ; CHECK-NEXT: ldp x30, x23, [sp], #48 // 16-byte Folded Reload
182 br i1 %cond, label %t, label %f
185 %ov = icmp ult i64 %x, %y
186 call void @call(i1 %ov)
187 br i1 %ov, label %end, label %f