1+ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
12
23; RUN: opt -passes=instcombine -S < %s 2>&1 | FileCheck %s
34
@@ -7,12 +8,14 @@ declare i32 @llvm.usub.sat.i32(i32, i32)
78declare i64 @llvm.usub.sat.i64 (i64 , i64 )
89
910define i8 @test_i8 (i8 %a , i8 %b ) {
10- ; CHECK-LABEL: @test_i8(
11- ; CHECK-NEXT: call i8 @llvm.usub.sat.i8(i8 %a, i8 96)
12- ; CHECK-NEXT: call i8 @llvm.usub.sat.i8(i8 %b, i8 112)
13- ; CHECK-NEXT: or i8
14- ; CHECK-NEXT: and i8
15- ; CHECK-NEXT: ret i8
11+ ; CHECK-LABEL: define i8 @test_i8(
12+ ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {
13+ ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[A]], i8 96)
14+ ; CHECK-NEXT: [[TMP2:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[B]], i8 112)
15+ ; CHECK-NEXT: [[TMP3:%.*]] = or i8 [[TMP1]], [[TMP2]]
16+ ; CHECK-NEXT: [[RES:%.*]] = and i8 [[TMP3]], -128
17+ ; CHECK-NEXT: ret i8 [[RES]]
18+ ;
1619
1720 %a_sub = call i8 @llvm.usub.sat.i8 (i8 %a , i8 223 )
1821 %b_sub = call i8 @llvm.usub.sat.i8 (i8 %b , i8 239 )
@@ -22,13 +25,33 @@ define i8 @test_i8(i8 %a, i8 %b) {
2225 ret i8 %res
2326}
2427
28+ define i8 @test_i8_ne (i8 %a , i8 %b ) {
29+ ; CHECK-LABEL: define i8 @test_i8_ne(
30+ ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {
31+ ; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[A]], i8 96)
32+ ; CHECK-NEXT: [[TMP2:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[B]], i8 112)
33+ ; CHECK-NEXT: [[TMP3:%.*]] = or i8 [[TMP1]], [[TMP2]]
34+ ; CHECK-NEXT: [[RES:%.*]] = and i8 [[TMP3]], -128
35+ ; CHECK-NEXT: ret i8 [[RES]]
36+ ;
37+
38+ %a_sub = call i8 @llvm.usub.sat.i8 (i8 %a , i8 223 )
39+ %b_sub = call i8 @llvm.usub.sat.i8 (i8 %b , i8 239 )
40+ %or = or i8 %a_sub , %b_sub
41+ %cmp = icmp ne i8 %or , 0
42+ %res = select i1 %cmp , i8 128 , i8 0
43+ ret i8 %res
44+ }
45+
2546define i16 @test_i16 (i16 %a , i16 %b ) {
26- ; CHECK-LABEL: @test_i16(
27- ; CHECK-NEXT: call i16 @llvm.usub.sat.i16(i16 %a, i16 32642)
28- ; CHECK-NEXT: call i16 @llvm.usub.sat.i16(i16 %b, i16 32656)
29- ; CHECK-NEXT: or i16
30- ; CHECK-NEXT: and i16
31- ; CHECK-NEXT: ret i16
47+ ; CHECK-LABEL: define i16 @test_i16(
48+ ; CHECK-SAME: i16 [[A:%.*]], i16 [[B:%.*]]) {
49+ ; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.usub.sat.i16(i16 [[A]], i16 32642)
50+ ; CHECK-NEXT: [[TMP2:%.*]] = call i16 @llvm.usub.sat.i16(i16 [[B]], i16 32656)
51+ ; CHECK-NEXT: [[TMP3:%.*]] = or i16 [[TMP1]], [[TMP2]]
52+ ; CHECK-NEXT: [[RES:%.*]] = and i16 [[TMP3]], -32768
53+ ; CHECK-NEXT: ret i16 [[RES]]
54+ ;
3255
3356 %a_sub = call i16 @llvm.usub.sat.i16 (i16 %a , i16 65409 )
3457 %b_sub = call i16 @llvm.usub.sat.i16 (i16 %b , i16 65423 )
@@ -39,12 +62,14 @@ define i16 @test_i16(i16 %a, i16 %b) {
3962}
4063
4164define i32 @test_i32 (i32 %a , i32 %b ) {
42- ; CHECK-LABEL: @test_i32(
43- ; CHECK-NEXT: call i32 @llvm.usub.sat.i32(i32 %a, i32 224)
44- ; CHECK-NEXT: call i32 @llvm.usub.sat.i32(i32 %b, i32 240)
45- ; CHECK-NEXT: or i32
46- ; CHECK-NEXT: and i32
47- ; CHECK-NEXT: ret i32
65+ ; CHECK-LABEL: define i32 @test_i32(
66+ ; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
67+ ; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[A]], i32 224)
68+ ; CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[B]], i32 240)
69+ ; CHECK-NEXT: [[TMP3:%.*]] = or i32 [[TMP1]], [[TMP2]]
70+ ; CHECK-NEXT: [[RES:%.*]] = and i32 [[TMP3]], -2147483648
71+ ; CHECK-NEXT: ret i32 [[RES]]
72+ ;
4873
4974 %a_sub = call i32 @llvm.usub.sat.i32 (i32 %a , i32 2147483871 )
5075 %b_sub = call i32 @llvm.usub.sat.i32 (i32 %b , i32 2147483887 )
@@ -55,12 +80,14 @@ define i32 @test_i32(i32 %a, i32 %b) {
5580}
5681
5782define i64 @test_i64 (i64 %a , i64 %b ) {
58- ; CHECK-LABEL: @test_i64(
59- ; CHECK-NEXT: call i64 @llvm.usub.sat.i64(i64 %a, i64 224)
60- ; CHECK-NEXT: call i64 @llvm.usub.sat.i64(i64 %b, i64 240)
61- ; CHECK-NEXT: or i64
62- ; CHECK-NEXT: and i64
63- ; CHECK-NEXT: ret i64
83+ ; CHECK-LABEL: define i64 @test_i64(
84+ ; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) {
85+ ; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A]], i64 224)
86+ ; CHECK-NEXT: [[TMP2:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[B]], i64 240)
87+ ; CHECK-NEXT: [[TMP3:%.*]] = or i64 [[TMP1]], [[TMP2]]
88+ ; CHECK-NEXT: [[RES:%.*]] = and i64 [[TMP3]], -9223372036854775808
89+ ; CHECK-NEXT: ret i64 [[RES]]
90+ ;
6491
6592 %a_sub = call i64 @llvm.usub.sat.i64 (i64 %a , i64 9223372036854776031 )
6693 %b_sub = call i64 @llvm.usub.sat.i64 (i64 %b , i64 9223372036854776047 )
@@ -71,13 +98,15 @@ define i64 @test_i64(i64 %a, i64 %b) {
7198}
7299
73100define i32 @no_fold_due_to_small_K (i32 %a , i32 %b ) {
74- ; CHECK-LABEL: @no_fold_due_to_small_K(
75- ; CHECK: call i32 @llvm.usub.sat.i32(i32 %a, i32 100)
76- ; CHECK: call i32 @llvm.usub.sat.i32(i32 %b, i32 239)
77- ; CHECK: or i32
78- ; CHECK: icmp eq i32
79- ; CHECK: select
80- ; CHECK: ret i32
101+ ; CHECK-LABEL: define i32 @no_fold_due_to_small_K(
102+ ; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
103+ ; CHECK-NEXT: [[A_SUB:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[A]], i32 100)
104+ ; CHECK-NEXT: [[B_SUB:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[B]], i32 239)
105+ ; CHECK-NEXT: [[OR:%.*]] = or i32 [[A_SUB]], [[B_SUB]]
106+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[OR]], 0
107+ ; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i32 0, i32 -2147483648
108+ ; CHECK-NEXT: ret i32 [[RES]]
109+ ;
81110
82111 %a_sub = call i32 @llvm.usub.sat.i32 (i32 %a , i32 100 )
83112 %b_sub = call i32 @llvm.usub.sat.i32 (i32 %b , i32 239 )
@@ -88,13 +117,15 @@ define i32 @no_fold_due_to_small_K(i32 %a, i32 %b) {
88117}
89118
90119define i32 @commuted_test_neg (i32 %a , i32 %b ) {
91- ; CHECK-LABEL: @commuted_test_neg(
92- ; CHECK-NEXT: call i32 @llvm.usub.sat.i32(i32 %b, i32 239)
93- ; CHECK-NEXT: call i32 @llvm.usub.sat.i32(i32 %a, i32 223)
94- ; CHECK-NEXT: or i32
95- ; CHECK-NEXT: icmp eq i32
96- ; CHECK-NEXT: select
97- ; CHECK-NEXT: ret i32
120+ ; CHECK-LABEL: define i32 @commuted_test_neg(
121+ ; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
122+ ; CHECK-NEXT: [[B_SUB:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[B]], i32 239)
123+ ; CHECK-NEXT: [[A_SUB:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[A]], i32 223)
124+ ; CHECK-NEXT: [[OR:%.*]] = or i32 [[B_SUB]], [[A_SUB]]
125+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[OR]], 0
126+ ; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i32 0, i32 -2147483648
127+ ; CHECK-NEXT: ret i32 [[RES]]
128+ ;
98129
99130 %b_sub = call i32 @llvm.usub.sat.i32 (i32 %b , i32 239 )
100131 %a_sub = call i32 @llvm.usub.sat.i32 (i32 %a , i32 223 )
@@ -104,23 +135,72 @@ define i32 @commuted_test_neg(i32 %a, i32 %b) {
104135 ret i32 %res
105136}
106137define <4 x i32 > @vector_test (<4 x i32 > %a , <4 x i32 > %b ) {
107- ; CHECK-LABEL: @vector_test(
108- ; CHECK-NEXT: call <4 x i32> @llvm.usub.sat.v4i32(<4 x i32> %a, <4 x i32> splat (i32 224))
109- ; CHECK-NEXT: call <4 x i32> @llvm.usub.sat.v4i32(<4 x i32> %b, <4 x i32> splat (i32 240))
110- ; CHECK-NEXT: or <4 x i32>
111- ; CHECK-NEXT: and <4 x i32>
112- ; CHECK-NEXT: ret <4 x i32>
138+ ; CHECK-LABEL: define <4 x i32> @vector_test(
139+ ; CHECK-SAME: <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]]) {
140+ ; CHECK-NEXT: [[TMP1:%.*]] = call <4 x i32> @llvm.usub.sat.v4i32(<4 x i32> [[A]], <4 x i32> splat (i32 224))
141+ ; CHECK-NEXT: [[TMP2:%.*]] = call <4 x i32> @llvm.usub.sat.v4i32(<4 x i32> [[B]], <4 x i32> splat (i32 240))
142+ ; CHECK-NEXT: [[TMP3:%.*]] = or <4 x i32> [[TMP1]], [[TMP2]]
143+ ; CHECK-NEXT: [[RES:%.*]] = and <4 x i32> [[TMP3]], splat (i32 -2147483648)
144+ ; CHECK-NEXT: ret <4 x i32> [[RES]]
145+ ;
146+
147+
148+ %a_sub = call <4 x i32 > @llvm.usub.sat.v4i32 (
149+ <4 x i32 > %a ,
150+ <4 x i32 > <i32 2147483871 , i32 2147483871 , i32 2147483871 , i32 2147483871 >)
151+ %b_sub = call <4 x i32 > @llvm.usub.sat.v4i32 (
152+ <4 x i32 > %b ,
153+ <4 x i32 > <i32 2147483887 , i32 2147483887 , i32 2147483887 , i32 2147483887 >)
154+ %or = or <4 x i32 > %a_sub , %b_sub
155+ %cmp = icmp eq <4 x i32 > %or , zeroinitializer
156+ %res = select <4 x i1 > %cmp , <4 x i32 > zeroinitializer ,
157+ <4 x i32 > <i32 -2147483648 , i32 -2147483648 , i32 -2147483648 , i32 -2147483648 >
158+ ret <4 x i32 > %res
159+ }
160+
161+ define <4 x i32 > @vector_negative_test (<4 x i32 > %a , <4 x i32 > %b ) {
162+ ; CHECK-LABEL: define <4 x i32> @vector_negative_test(
163+ ; CHECK-SAME: <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]]) {
164+ ; CHECK-NEXT: [[A_SUB:%.*]] = call <4 x i32> @llvm.usub.sat.v4i32(<4 x i32> [[A]], <4 x i32> <i32 -2147483425, i32 0, i32 -2147483425, i32 -2147483425>)
165+ ; CHECK-NEXT: [[B_SUB:%.*]] = call <4 x i32> @llvm.usub.sat.v4i32(<4 x i32> [[B]], <4 x i32> splat (i32 -2147483409))
166+ ; CHECK-NEXT: [[OR:%.*]] = or <4 x i32> [[A_SUB]], [[B_SUB]]
167+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <4 x i32> [[OR]], zeroinitializer
168+ ; CHECK-NEXT: [[RES:%.*]] = select <4 x i1> [[CMP]], <4 x i32> zeroinitializer, <4 x i32> splat (i32 -2147483648)
169+ ; CHECK-NEXT: ret <4 x i32> [[RES]]
170+ ;
171+ %a_sub = call <4 x i32 > @llvm.usub.sat.v4i32 (
172+ <4 x i32 > %a ,
173+ <4 x i32 > <i32 2147483871 , i32 0 , i32 2147483871 , i32 2147483871 >)
174+ %b_sub = call <4 x i32 > @llvm.usub.sat.v4i32 (
175+ <4 x i32 > %b ,
176+ <4 x i32 > <i32 2147483887 , i32 2147483887 , i32 2147483887 , i32 2147483887 >)
177+ %or = or <4 x i32 > %a_sub , %b_sub
178+ %cmp = icmp eq <4 x i32 > %or , zeroinitializer
179+ %res = select <4 x i1 > %cmp , <4 x i32 > zeroinitializer ,
180+ <4 x i32 > <i32 -2147483648 , i32 -2147483648 , i32 -2147483648 , i32 -2147483648 >
181+ ret <4 x i32 > %res
182+ }
183+
184+ define <4 x i32 > @vector_ne_test (<4 x i32 > %a , <4 x i32 > %b ) {
185+ ; CHECK-LABEL: define <4 x i32> @vector_ne_test(
186+ ; CHECK-SAME: <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]]) {
187+ ; CHECK-NEXT: [[TMP1:%.*]] = call <4 x i32> @llvm.usub.sat.v4i32(<4 x i32> [[A]], <4 x i32> splat (i32 224))
188+ ; CHECK-NEXT: [[TMP2:%.*]] = call <4 x i32> @llvm.usub.sat.v4i32(<4 x i32> [[B]], <4 x i32> splat (i32 240))
189+ ; CHECK-NEXT: [[TMP3:%.*]] = or <4 x i32> [[TMP1]], [[TMP2]]
190+ ; CHECK-NEXT: [[RES:%.*]] = and <4 x i32> [[TMP3]], splat (i32 -2147483648)
191+ ; CHECK-NEXT: ret <4 x i32> [[RES]]
192+ ;
113193
114194
115195 %a_sub = call <4 x i32 > @llvm.usub.sat.v4i32 (
116- <4 x i32 > %a ,
117- <4 x i32 > <i32 2147483871 , i32 2147483871 , i32 2147483871 , i32 2147483871 >)
196+ <4 x i32 > %a ,
197+ <4 x i32 > <i32 2147483871 , i32 2147483871 , i32 2147483871 , i32 2147483871 >)
118198 %b_sub = call <4 x i32 > @llvm.usub.sat.v4i32 (
119- <4 x i32 > %b ,
120- <4 x i32 > <i32 2147483887 , i32 2147483887 , i32 2147483887 , i32 2147483887 >)
199+ <4 x i32 > %b ,
200+ <4 x i32 > <i32 2147483887 , i32 2147483887 , i32 2147483887 , i32 2147483887 >)
121201 %or = or <4 x i32 > %a_sub , %b_sub
122202 %cmp = icmp eq <4 x i32 > %or , zeroinitializer
123203 %res = select <4 x i1 > %cmp , <4 x i32 > zeroinitializer ,
124- <4 x i32 > <i32 -2147483648 , i32 -2147483648 , i32 -2147483648 , i32 -2147483648 >
204+ <4 x i32 > <i32 -2147483648 , i32 -2147483648 , i32 -2147483648 , i32 -2147483648 >
125205 ret <4 x i32 > %res
126206}
0 commit comments