[TTI] getTypeBasedIntrinsicInstrCost - add basic handling for strided load/store...
[llvm-project.git] / llvm / test / Transforms / InstSimplify / icmp-monotonic.ll
blobe1a4ee91bd15c51cc836a76e7e49f216ff38780d
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2 ; RUN: opt -S -passes=instsimplify < %s | FileCheck %s
4 define i1 @lshr_or_ule(i32 %x, i32 %y, i32 %z) {
5 ; CHECK-LABEL: define i1 @lshr_or_ule(
6 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
7 ; CHECK-NEXT:    ret i1 true
9   %op1 = lshr i32 %x, %y
10   %op2 = or i32 %x, %z
11   %cmp = icmp ule i32 %op1, %op2
12   ret i1 %cmp
15 define i1 @lshr_or_uge_swapped(i32 %x, i32 %y, i32 %z) {
16 ; CHECK-LABEL: define i1 @lshr_or_uge_swapped(
17 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
18 ; CHECK-NEXT:    ret i1 true
20   %op1 = lshr i32 %x, %y
21   %op2 = or i32 %x, %z
22   %cmp = icmp uge i32 %op2, %op1
23   ret i1 %cmp
26 define i1 @lshr_or_ugt(i32 %x, i32 %y, i32 %z) {
27 ; CHECK-LABEL: define i1 @lshr_or_ugt(
28 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
29 ; CHECK-NEXT:    ret i1 false
31   %op1 = lshr i32 %x, %y
32   %op2 = or i32 %x, %z
33   %cmp = icmp ugt i32 %op1, %op2
34   ret i1 %cmp
37 define i1 @lshr_or_ult_wrong_pred(i32 %x, i32 %y, i32 %z) {
38 ; CHECK-LABEL: define i1 @lshr_or_ult_wrong_pred(
39 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
40 ; CHECK-NEXT:    [[OP1:%.*]] = lshr i32 [[X]], [[Y]]
41 ; CHECK-NEXT:    [[OP2:%.*]] = or i32 [[X]], [[Z]]
42 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[OP1]], [[OP2]]
43 ; CHECK-NEXT:    ret i1 [[CMP]]
45   %op1 = lshr i32 %x, %y
46   %op2 = or i32 %x, %z
47   %cmp = icmp ult i32 %op1, %op2
48   ret i1 %cmp
51 define i1 @lshr_or_sle_wrong_pred(i32 %x, i32 %y, i32 %z) {
52 ; CHECK-LABEL: define i1 @lshr_or_sle_wrong_pred(
53 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
54 ; CHECK-NEXT:    [[OP1:%.*]] = lshr i32 [[X]], [[Y]]
55 ; CHECK-NEXT:    [[OP2:%.*]] = or i32 [[X]], [[Z]]
56 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sle i32 [[OP1]], [[OP2]]
57 ; CHECK-NEXT:    ret i1 [[CMP]]
59   %op1 = lshr i32 %x, %y
60   %op2 = or i32 %x, %z
61   %cmp = icmp sle i32 %op1, %op2
62   ret i1 %cmp
65 define i1 @lshr_or_swapped_ule(i32 %x, i32 %y, i32 %z) {
66 ; CHECK-LABEL: define i1 @lshr_or_swapped_ule(
67 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
68 ; CHECK-NEXT:    ret i1 true
70   %op1 = lshr i32 %x, %y
71   %op2 = or i32 %z, %x
72   %cmp = icmp ule i32 %op1, %op2
73   ret i1 %cmp
76 define i1 @lshr_or_ule_invalid_swapped(i32 %x, i32 %y, i32 %z) {
77 ; CHECK-LABEL: define i1 @lshr_or_ule_invalid_swapped(
78 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
79 ; CHECK-NEXT:    [[OP1:%.*]] = lshr i32 [[Y]], [[X]]
80 ; CHECK-NEXT:    [[OP2:%.*]] = or i32 [[X]], [[Z]]
81 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i32 [[OP1]], [[OP2]]
82 ; CHECK-NEXT:    ret i1 [[CMP]]
84   %op1 = lshr i32 %y, %x
85   %op2 = or i32 %x, %z
86   %cmp = icmp ule i32 %op1, %op2
87   ret i1 %cmp
90 define i1 @and_uadd_sat_ule(i32 %x, i32 %y, i32 %z) {
91 ; CHECK-LABEL: define i1 @and_uadd_sat_ule(
92 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
93 ; CHECK-NEXT:    ret i1 true
95   %op1 = and i32 %x, %y
96   %op2 = call i32 @llvm.uadd.sat(i32 %x, i32 %z)
97   %cmp = icmp ule i32 %op1, %op2
98   ret i1 %cmp
101 define i1 @urem_or_ule(i32 %x, i32 %y, i32 %z) {
102 ; CHECK-LABEL: define i1 @urem_or_ule(
103 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
104 ; CHECK-NEXT:    ret i1 true
106   %op1 = urem i32 %x, %y
107   %op2 = or i32 %x, %z
108   %cmp = icmp ule i32 %op1, %op2
109   ret i1 %cmp
112 define i1 @urem_or_ule_invalid_swapped(i32 %x, i32 %y, i32 %z) {
113 ; CHECK-LABEL: define i1 @urem_or_ule_invalid_swapped(
114 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
115 ; CHECK-NEXT:    [[OP1:%.*]] = urem i32 [[Y]], [[X]]
116 ; CHECK-NEXT:    [[OP2:%.*]] = or i32 [[X]], [[Z]]
117 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i32 [[OP1]], [[OP2]]
118 ; CHECK-NEXT:    ret i1 [[CMP]]
120   %op1 = urem i32 %y, %x
121   %op2 = or i32 %x, %z
122   %cmp = icmp ule i32 %op1, %op2
123   ret i1 %cmp
126 define i1 @udiv_or_ule(i32 %x, i32 %y, i32 %z) {
127 ; CHECK-LABEL: define i1 @udiv_or_ule(
128 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
129 ; CHECK-NEXT:    ret i1 true
131   %op1 = udiv i32 %x, %y
132   %op2 = or i32 %x, %z
133   %cmp = icmp ule i32 %op1, %op2
134   ret i1 %cmp
137 define i1 @udiv_or_ule_invalid_swapped(i32 %x, i32 %y, i32 %z) {
138 ; CHECK-LABEL: define i1 @udiv_or_ule_invalid_swapped(
139 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
140 ; CHECK-NEXT:    [[OP1:%.*]] = udiv i32 [[Y]], [[X]]
141 ; CHECK-NEXT:    [[OP2:%.*]] = or i32 [[X]], [[Z]]
142 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i32 [[OP1]], [[OP2]]
143 ; CHECK-NEXT:    ret i1 [[CMP]]
145   %op1 = udiv i32 %y, %x
146   %op2 = or i32 %x, %z
147   %cmp = icmp ule i32 %op1, %op2
148   ret i1 %cmp
151 define i1 @usub_sat_uadd_sat_ule(i32 %x, i32 %y, i32 %z) {
152 ; CHECK-LABEL: define i1 @usub_sat_uadd_sat_ule(
153 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
154 ; CHECK-NEXT:    ret i1 true
156   %op1 = call i32 @llvm.usub.sat(i32 %x, i32 %y)
157   %op2 = call i32 @llvm.uadd.sat(i32 %x, i32 %z)
158   %cmp = icmp ule i32 %op1, %op2
159   ret i1 %cmp
162 define i1 @usub_sat_uadd_sat_ule_invalid_swapped(i32 %x, i32 %y, i32 %z) {
163 ; CHECK-LABEL: define i1 @usub_sat_uadd_sat_ule_invalid_swapped(
164 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
165 ; CHECK-NEXT:    [[OP1:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[Y]], i32 [[X]])
166 ; CHECK-NEXT:    [[OP2:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[X]], i32 [[Z]])
167 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i32 [[OP1]], [[OP2]]
168 ; CHECK-NEXT:    ret i1 [[CMP]]
170   %op1 = call i32 @llvm.usub.sat(i32 %y, i32 %x)
171   %op2 = call i32 @llvm.uadd.sat(i32 %x, i32 %z)
172   %cmp = icmp ule i32 %op1, %op2
173   ret i1 %cmp
176 define i1 @lshr_or_ule_no_common_op(i32 %x, i32 %y, i32 %z, i32 %w) {
177 ; CHECK-LABEL: define i1 @lshr_or_ule_no_common_op(
178 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]], i32 [[W:%.*]]) {
179 ; CHECK-NEXT:    [[OP1:%.*]] = lshr i32 [[X]], [[Y]]
180 ; CHECK-NEXT:    [[OP2:%.*]] = or i32 [[W]], [[Z]]
181 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i32 [[OP1]], [[OP2]]
182 ; CHECK-NEXT:    ret i1 [[CMP]]
184   %op1 = lshr i32 %x, %y
185   %op2 = or i32 %w, %z
186   %cmp = icmp ule i32 %op1, %op2
187   ret i1 %cmp
190 define i1 @lshr_or_ule_nested(i32 %x, i32 %y, i32 %z, i32 %w) {
191 ; CHECK-LABEL: define i1 @lshr_or_ule_nested(
192 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]], i32 [[W:%.*]]) {
193 ; CHECK-NEXT:    [[OP1:%.*]] = lshr i32 [[X]], [[Y]]
194 ; CHECK-NEXT:    [[OP2:%.*]] = or i32 [[X]], [[Z]]
195 ; CHECK-NEXT:    [[OP3:%.*]] = or i32 [[OP2]], [[W]]
196 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i32 [[OP1]], [[OP3]]
197 ; CHECK-NEXT:    ret i1 [[CMP]]
199   %op1 = lshr i32 %x, %y
200   %op2 = or i32 %x, %z
201   %op3 = or i32 %op2, %w
202   %cmp = icmp ule i32 %op1, %op3
203   ret i1 %cmp
206 define i1 @lshr_add_ule_non_monotonic(i32 %x, i32 %y, i32 %z) {
207 ; CHECK-LABEL: define i1 @lshr_add_ule_non_monotonic(
208 ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
209 ; CHECK-NEXT:    [[OP1:%.*]] = lshr i32 [[X]], [[Y]]
210 ; CHECK-NEXT:    [[OP2:%.*]] = add i32 [[X]], [[Z]]
211 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ule i32 [[OP1]], [[OP2]]
212 ; CHECK-NEXT:    ret i1 [[CMP]]
214   %op1 = lshr i32 %x, %y
215   %op2 = add i32 %x, %z
216   %cmp = icmp ule i32 %op1, %op2
217   ret i1 %cmp