[InstCombine] Signed saturation patterns
[llvm-core.git] / test / Transforms / InstCombine / canonicalize-low-bit-mask-and-icmp-eq-to-icmp-ule.ll
blobdc5fbebc2303eff06e8b7f6b6981a8a003a820e2
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
4 ; https://bugs.llvm.org/show_bug.cgi?id=38123
6 ; Pattern:
7 ;   x & (-1 >> y) == x
8 ; Should be transformed into:
9 ;   x u<= (-1 >> y)
11 ; ============================================================================ ;
12 ; Basic positive tests
13 ; ============================================================================ ;
15 define i1 @p0(i8 %x, i8 %y) {
16 ; CHECK-LABEL: @p0(
17 ; CHECK-NEXT:    [[TMP0:%.*]] = lshr i8 -1, [[Y:%.*]]
18 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp uge i8 [[TMP0]], [[X:%.*]]
19 ; CHECK-NEXT:    ret i1 [[TMP1]]
21   %tmp0 = lshr i8 -1, %y
22   %tmp1 = and i8 %tmp0, %x
23   %ret = icmp eq i8 %tmp1, %x
24   ret i1 %ret
27 ; ============================================================================ ;
28 ; Vector tests
29 ; ============================================================================ ;
31 define <2 x i1> @p1_vec(<2 x i8> %x, <2 x i8> %y) {
32 ; CHECK-LABEL: @p1_vec(
33 ; CHECK-NEXT:    [[TMP0:%.*]] = lshr <2 x i8> <i8 -1, i8 -1>, [[Y:%.*]]
34 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp uge <2 x i8> [[TMP0]], [[X:%.*]]
35 ; CHECK-NEXT:    ret <2 x i1> [[TMP1]]
37   %tmp0 = lshr <2 x i8> <i8 -1, i8 -1>, %y
38   %tmp1 = and <2 x i8> %tmp0, %x
39   %ret = icmp eq <2 x i8> %tmp1, %x
40   ret <2 x i1> %ret
43 define <3 x i1> @p2_vec_undef(<3 x i8> %x, <3 x i8> %y) {
44 ; CHECK-LABEL: @p2_vec_undef(
45 ; CHECK-NEXT:    [[TMP0:%.*]] = lshr <3 x i8> <i8 -1, i8 undef, i8 -1>, [[Y:%.*]]
46 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp uge <3 x i8> [[TMP0]], [[X:%.*]]
47 ; CHECK-NEXT:    ret <3 x i1> [[TMP1]]
49   %tmp0 = lshr <3 x i8> <i8 -1, i8 undef, i8 -1>, %y
50   %tmp1 = and <3 x i8> %tmp0, %x
51   %ret = icmp eq <3 x i8> %tmp1, %x
52   ret <3 x i1> %ret
55 ; ============================================================================ ;
56 ; Commutativity tests.
57 ; ============================================================================ ;
59 declare i8 @gen8()
61 define i1 @c0(i8 %y) {
62 ; CHECK-LABEL: @c0(
63 ; CHECK-NEXT:    [[TMP0:%.*]] = lshr i8 -1, [[Y:%.*]]
64 ; CHECK-NEXT:    [[X:%.*]] = call i8 @gen8()
65 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ule i8 [[X]], [[TMP0]]
66 ; CHECK-NEXT:    ret i1 [[TMP1]]
68   %tmp0 = lshr i8 -1, %y
69   %x = call i8 @gen8()
70   %tmp1 = and i8 %x, %tmp0 ; swapped order
71   %ret = icmp eq i8 %tmp1, %x
72   ret i1 %ret
75 define i1 @c1(i8 %y) {
76 ; CHECK-LABEL: @c1(
77 ; CHECK-NEXT:    [[TMP0:%.*]] = lshr i8 -1, [[Y:%.*]]
78 ; CHECK-NEXT:    [[X:%.*]] = call i8 @gen8()
79 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ule i8 [[X]], [[TMP0]]
80 ; CHECK-NEXT:    ret i1 [[TMP1]]
82   %tmp0 = lshr i8 -1, %y
83   %x = call i8 @gen8()
84   %tmp1 = and i8 %tmp0, %x
85   %ret = icmp eq i8 %x, %tmp1 ; swapped order
86   ret i1 %ret
89 define i1 @c2(i8 %y) {
90 ; CHECK-LABEL: @c2(
91 ; CHECK-NEXT:    [[TMP0:%.*]] = lshr i8 -1, [[Y:%.*]]
92 ; CHECK-NEXT:    [[X:%.*]] = call i8 @gen8()
93 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ule i8 [[X]], [[TMP0]]
94 ; CHECK-NEXT:    ret i1 [[TMP1]]
96   %tmp0 = lshr i8 -1, %y
97   %x = call i8 @gen8()
98   %tmp1 = and i8 %x, %tmp0 ; swapped order
99   %ret = icmp eq i8 %x, %tmp1 ; swapped order
100   ret i1 %ret
103 ; ============================================================================ ;
104 ; One-use tests. We don't care about multi-uses here.
105 ; ============================================================================ ;
107 declare void @use8(i8)
109 define i1 @oneuse0(i8 %x, i8 %y) {
110 ; CHECK-LABEL: @oneuse0(
111 ; CHECK-NEXT:    [[TMP0:%.*]] = lshr i8 -1, [[Y:%.*]]
112 ; CHECK-NEXT:    call void @use8(i8 [[TMP0]])
113 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp uge i8 [[TMP0]], [[X:%.*]]
114 ; CHECK-NEXT:    ret i1 [[TMP1]]
116   %tmp0 = lshr i8 -1, %y
117   call void @use8(i8 %tmp0)
118   %tmp1 = and i8 %tmp0, %x
119   %ret = icmp eq i8 %tmp1, %x
120   ret i1 %ret
123 define i1 @oneuse1(i8 %x, i8 %y) {
124 ; CHECK-LABEL: @oneuse1(
125 ; CHECK-NEXT:    [[TMP0:%.*]] = lshr i8 -1, [[Y:%.*]]
126 ; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[TMP0]], [[X:%.*]]
127 ; CHECK-NEXT:    call void @use8(i8 [[TMP1]])
128 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp uge i8 [[TMP0]], [[X]]
129 ; CHECK-NEXT:    ret i1 [[TMP1]]
131   %tmp0 = lshr i8 -1, %y
132   %tmp1 = and i8 %tmp0, %x
133   call void @use8(i8 %tmp1)
134   %ret = icmp eq i8 %tmp1, %x
135   ret i1 %ret
138 define i1 @oneuse2(i8 %x, i8 %y) {
139 ; CHECK-LABEL: @oneuse2(
140 ; CHECK-NEXT:    [[TMP0:%.*]] = lshr i8 -1, [[Y:%.*]]
141 ; CHECK-NEXT:    call void @use8(i8 [[TMP0]])
142 ; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[TMP0]], [[X:%.*]]
143 ; CHECK-NEXT:    call void @use8(i8 [[TMP1]])
144 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp uge i8 [[TMP0]], [[X]]
145 ; CHECK-NEXT:    ret i1 [[TMP1]]
147   %tmp0 = lshr i8 -1, %y
148   call void @use8(i8 %tmp0)
149   %tmp1 = and i8 %tmp0, %x
150   call void @use8(i8 %tmp1)
151   %ret = icmp eq i8 %tmp1, %x
152   ret i1 %ret
155 ; ============================================================================ ;
156 ; Negative tests
157 ; ============================================================================ ;
159 define i1 @n0(i8 %x, i8 %y, i8 %notx) {
160 ; CHECK-LABEL: @n0(
161 ; CHECK-NEXT:    [[TMP0:%.*]] = lshr i8 -1, [[Y:%.*]]
162 ; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[TMP0]], [[X:%.*]]
163 ; CHECK-NEXT:    [[RET:%.*]] = icmp eq i8 [[TMP1]], [[NOTX:%.*]]
164 ; CHECK-NEXT:    ret i1 [[RET]]
166   %tmp0 = lshr i8 -1, %y
167   %tmp1 = and i8 %tmp0, %x
168   %ret = icmp eq i8 %tmp1, %notx ; not %x
169   ret i1 %ret