1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -instcombine -S | FileCheck %s
3
4define i1 @test_nuw_and_unsigned_pred(i64 %x) {
5; CHECK-LABEL: @test_nuw_and_unsigned_pred(
6; CHECK-NEXT:    [[Z:%.*]] = icmp ugt i64 [[X:%.*]], 7
7; CHECK-NEXT:    ret i1 [[Z]]
8;
9  %y = sub nuw i64 10, %x
10  %z = icmp ult i64 %y, 3
11  ret i1 %z
12}
13
14define i1 @test_nsw_and_signed_pred(i64 %x) {
15; CHECK-LABEL: @test_nsw_and_signed_pred(
16; CHECK-NEXT:    [[Z:%.*]] = icmp slt i64 [[X:%.*]], -7
17; CHECK-NEXT:    ret i1 [[Z]]
18;
19  %y = sub nsw i64 3, %x
20  %z = icmp sgt i64 %y, 10
21  ret i1 %z
22}
23
24define i1 @test_nuw_nsw_and_unsigned_pred(i64 %x) {
25; CHECK-LABEL: @test_nuw_nsw_and_unsigned_pred(
26; CHECK-NEXT:    [[Z:%.*]] = icmp ugt i64 [[X:%.*]], 6
27; CHECK-NEXT:    ret i1 [[Z]]
28;
29  %y = sub nuw nsw i64 10, %x
30  %z = icmp ule i64 %y, 3
31  ret i1 %z
32}
33
34define i1 @test_nuw_nsw_and_signed_pred(i64 %x) {
35; CHECK-LABEL: @test_nuw_nsw_and_signed_pred(
36; CHECK-NEXT:    [[Z:%.*]] = icmp sgt i64 [[X:%.*]], 7
37; CHECK-NEXT:    ret i1 [[Z]]
38;
39  %y = sub nuw nsw i64 10, %x
40  %z = icmp slt i64 %y, 3
41  ret i1 %z
42}
43
44define i1 @test_negative_nuw_and_signed_pred(i64 %x) {
45; CHECK-LABEL: @test_negative_nuw_and_signed_pred(
46; CHECK-NEXT:    [[Y:%.*]] = sub nuw i64 10, [[X:%.*]]
47; CHECK-NEXT:    [[Z:%.*]] = icmp slt i64 [[Y]], 3
48; CHECK-NEXT:    ret i1 [[Z]]
49;
50  %y = sub nuw i64 10, %x
51  %z = icmp slt i64 %y, 3
52  ret i1 %z
53}
54
55define i1 @test_negative_nsw_and_unsigned_pred(i64 %x) {
56; CHECK-LABEL: @test_negative_nsw_and_unsigned_pred(
57; CHECK-NEXT:    [[Y:%.*]] = sub nsw i64 10, [[X:%.*]]
58; CHECK-NEXT:    [[Z:%.*]] = icmp ult i64 [[Y]], 3
59; CHECK-NEXT:    ret i1 [[Z]]
60;
61  %y = sub nsw i64 10, %x
62  %z = icmp ult i64 %y, 3
63  ret i1 %z
64}
65
66define i1 @test_negative_combined_sub_unsigned_overflow(i64 %x) {
67; CHECK-LABEL: @test_negative_combined_sub_unsigned_overflow(
68; CHECK-NEXT:    [[Y:%.*]] = sub nuw i64 10, [[X:%.*]]
69; CHECK-NEXT:    [[Z:%.*]] = icmp ult i64 [[Y]], 11
70; CHECK-NEXT:    ret i1 [[Z]]
71;
72  %y = sub nuw i64 10, %x
73  %z = icmp ult i64 %y, 11
74  ret i1 %z
75}
76
77define i1 @test_negative_combined_sub_signed_overflow(i8 %x) {
78; CHECK-LABEL: @test_negative_combined_sub_signed_overflow(
79; CHECK-NEXT:    [[Y:%.*]] = sub nsw i8 127, [[X:%.*]]
80; CHECK-NEXT:    [[Z:%.*]] = icmp slt i8 [[Y]], -1
81; CHECK-NEXT:    ret i1 [[Z]]
82;
83  %y = sub nsw i8 127, %x
84  %z = icmp slt i8 %y, -1
85  ret i1 %z
86}
87
88define i1 @test_sub_0_Y_eq_0(i8 %y) {
89; CHECK-LABEL: @test_sub_0_Y_eq_0(
90; CHECK-NEXT:    [[Z:%.*]] = icmp eq i8 [[Y:%.*]], 0
91; CHECK-NEXT:    ret i1 [[Z]]
92;
93  %s = sub i8 0, %y
94  %z = icmp eq i8 %s, 0
95  ret i1 %z
96}
97
98define i1 @test_sub_0_Y_ne_0(i8 %y) {
99; CHECK-LABEL: @test_sub_0_Y_ne_0(
100; CHECK-NEXT:    [[Z:%.*]] = icmp ne i8 [[Y:%.*]], 0
101; CHECK-NEXT:    ret i1 [[Z]]
102;
103  %s = sub i8 0, %y
104  %z = icmp ne i8 %s, 0
105  ret i1 %z
106}
107
108define i1 @test_sub_4_Y_ne_4(i8 %y) {
109; CHECK-LABEL: @test_sub_4_Y_ne_4(
110; CHECK-NEXT:    [[Z:%.*]] = icmp ne i8 [[Y:%.*]], 0
111; CHECK-NEXT:    ret i1 [[Z]]
112;
113  %s = sub i8 4, %y
114  %z = icmp ne i8 %s, 4
115  ret i1 %z
116}
117
118define i1 @test_sub_127_Y_eq_127(i8 %y) {
119; CHECK-LABEL: @test_sub_127_Y_eq_127(
120; CHECK-NEXT:    [[Z:%.*]] = icmp eq i8 [[Y:%.*]], 0
121; CHECK-NEXT:    ret i1 [[Z]]
122;
123  %s = sub i8 127, %y
124  %z = icmp eq i8 %s, 127
125  ret i1 %z
126}
127
128define i1 @test_sub_255_Y_eq_255(i8 %y) {
129; CHECK-LABEL: @test_sub_255_Y_eq_255(
130; CHECK-NEXT:    [[Z:%.*]] = icmp eq i8 [[Y:%.*]], 0
131; CHECK-NEXT:    ret i1 [[Z]]
132;
133  %s = sub i8 255, %y
134  %z = icmp eq i8 %s, 255
135  ret i1 %z
136}
137define <2 x i1> @test_sub_255_Y_eq_255_vec(<2 x i8> %y) {
138; CHECK-LABEL: @test_sub_255_Y_eq_255_vec(
139; CHECK-NEXT:    [[Z:%.*]] = icmp eq <2 x i8> [[Y:%.*]], zeroinitializer
140; CHECK-NEXT:    ret <2 x i1> [[Z]]
141;
142  %s = sub <2 x i8> <i8 255, i8 255>, %y
143  %z = icmp eq <2 x i8> %s, <i8 255, i8 255>
144  ret <2 x i1> %z
145}
146
147define <2 x i1> @icmp_eq_sub_undef(<2 x i32> %a) {
148; CHECK-LABEL: @icmp_eq_sub_undef(
149; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[A:%.*]], <i32 5, i32 undef>
150; CHECK-NEXT:    ret <2 x i1> [[CMP]]
151;
152  %sub = sub <2 x i32> <i32 15, i32 undef>, %a
153  %cmp = icmp eq <2 x i32> %sub, <i32 10, i32 10>
154  ret <2 x i1> %cmp
155}
156
157define <2 x i1> @icmp_eq_sub_non_splat(<2 x i32> %a) {
158; CHECK-LABEL: @icmp_eq_sub_non_splat(
159; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[A:%.*]], <i32 5, i32 6>
160; CHECK-NEXT:    ret <2 x i1> [[CMP]]
161;
162  %sub = sub <2 x i32> <i32 15, i32 16>, %a
163  %cmp = icmp eq <2 x i32> %sub, <i32 10, i32 10>
164  ret <2 x i1> %cmp
165}
166
167define <2 x i1> @icmp_eq_sub_undef2(<2 x i32> %a) {
168; CHECK-LABEL: @icmp_eq_sub_undef2(
169; CHECK-NEXT:    [[SUB:%.*]] = sub <2 x i32> <i32 15, i32 15>, [[A:%.*]]
170; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[SUB]], <i32 10, i32 undef>
171; CHECK-NEXT:    ret <2 x i1> [[CMP]]
172;
173  %sub = sub <2 x i32> <i32 15, i32 15>, %a
174  %cmp = icmp eq <2 x i32> %sub, <i32 10, i32 undef>
175  ret <2 x i1> %cmp
176}
177
178define <2 x i1> @icmp_eq_sub_non_splat2(<2 x i32> %a) {
179; CHECK-LABEL: @icmp_eq_sub_non_splat2(
180; CHECK-NEXT:    [[SUB:%.*]] = sub <2 x i32> <i32 15, i32 15>, [[A:%.*]]
181; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[SUB]], <i32 10, i32 11>
182; CHECK-NEXT:    ret <2 x i1> [[CMP]]
183;
184  %sub = sub <2 x i32> <i32 15, i32 15>, %a
185  %cmp = icmp eq <2 x i32> %sub, <i32 10, i32 11>
186  ret <2 x i1> %cmp
187}
188