@@ -8,6 +8,95 @@ declare void @use(i64)
8
8
declare void @usei32 (i32 )
9
9
declare void @usei1 (i1 )
10
10
11
+ ; usub_sat((sub nuw C1, A), C2) to usub_sat(usub_sat(C1 - C2), A)
12
+ define i32 @usub_sat_C1_C2 (i32 %a ){
13
+ ; CHECK-LABEL: @usub_sat_C1_C2(
14
+ ; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.usub.sat.i32(i32 50, i32 [[A:%.*]])
15
+ ; CHECK-NEXT: ret i32 [[COND]]
16
+ ;
17
+ %add = sub nuw i32 64 , %a
18
+ %cond = call i32 @llvm.usub.sat.i32 (i32 %add , i32 14 )
19
+ ret i32 %cond
20
+ }
21
+
22
+ define i32 @usub_sat_C1_C2_produce_0 (i32 %a ){
23
+ ; CHECK-LABEL: @usub_sat_C1_C2_produce_0(
24
+ ; CHECK-NEXT: ret i32 0
25
+ ;
26
+ %add = sub nuw i32 14 , %a
27
+ %cond = call i32 @llvm.usub.sat.i32 (i32 %add , i32 14 )
28
+ ret i32 %cond
29
+ }
30
+
31
+ define i32 @usub_sat_C1_C2_produce_0_too (i32 %a ){
32
+ ; CHECK-LABEL: @usub_sat_C1_C2_produce_0_too(
33
+ ; CHECK-NEXT: ret i32 0
34
+ ;
35
+ %add = sub nuw i32 12 , %a
36
+ %cond = call i32 @llvm.usub.sat.i32 (i32 %add , i32 14 )
37
+ ret i32 %cond
38
+ }
39
+
40
+ ; vector tests
41
+ define <2 x i16 > @usub_sat_C1_C2_splat (<2 x i16 > %a ) {
42
+ ; CHECK-LABEL: @usub_sat_C1_C2_splat(
43
+ ; CHECK-NEXT: [[COND:%.*]] = call <2 x i16> @llvm.usub.sat.v2i16(<2 x i16> <i16 50, i16 50>, <2 x i16> [[A:%.*]])
44
+ ; CHECK-NEXT: ret <2 x i16> [[COND]]
45
+ ;
46
+ %add = sub nuw <2 x i16 > <i16 64 , i16 64 >, %a
47
+ %cond = call <2 x i16 > @llvm.usub.sat.v2i16 (<2 x i16 > %add , <2 x i16 > <i16 14 , i16 14 >)
48
+ ret <2 x i16 > %cond
49
+ }
50
+
51
+ define <2 x i16 > @usub_sat_C1_C2_non_splat (<2 x i16 > %a ) {
52
+ ; CHECK-LABEL: @usub_sat_C1_C2_non_splat(
53
+ ; CHECK-NEXT: [[COND:%.*]] = call <2 x i16> @llvm.usub.sat.v2i16(<2 x i16> <i16 30, i16 50>, <2 x i16> [[A:%.*]])
54
+ ; CHECK-NEXT: ret <2 x i16> [[COND]]
55
+ ;
56
+ %add = sub nuw <2 x i16 > <i16 50 , i16 64 >, %a
57
+ %cond = call <2 x i16 > @llvm.usub.sat.v2i16 (<2 x i16 > %add , <2 x i16 > <i16 20 , i16 14 >)
58
+ ret <2 x i16 > %cond
59
+ }
60
+
61
+ define <2 x i16 > @usub_sat_C1_C2_splat_produce_0 (<2 x i16 > %a ){
62
+ ; CHECK-LABEL: @usub_sat_C1_C2_splat_produce_0(
63
+ ; CHECK-NEXT: ret <2 x i16> zeroinitializer
64
+ ;
65
+ %add = sub nuw <2 x i16 > <i16 14 , i16 14 >, %a
66
+ %cond = call <2 x i16 > @llvm.usub.sat.v2i16 (<2 x i16 > %add , <2 x i16 > <i16 14 , i16 14 >)
67
+ ret <2 x i16 > %cond
68
+ }
69
+
70
+ define <2 x i16 > @usub_sat_C1_C2_splat_produce_0_too (<2 x i16 > %a ){
71
+ ; CHECK-LABEL: @usub_sat_C1_C2_splat_produce_0_too(
72
+ ; CHECK-NEXT: ret <2 x i16> zeroinitializer
73
+ ;
74
+ %add = sub nuw <2 x i16 > <i16 12 , i16 12 >, %a
75
+ %cond = call <2 x i16 > @llvm.usub.sat.v2i16 (<2 x i16 > %add , <2 x i16 > <i16 14 , i16 14 >)
76
+ ret <2 x i16 > %cond
77
+ }
78
+
79
+ define <2 x i16 > @usub_sat_C1_C2_non_splat_produce_0_too (<2 x i16 > %a ){
80
+ ; CHECK-LABEL: @usub_sat_C1_C2_non_splat_produce_0_too(
81
+ ; CHECK-NEXT: ret <2 x i16> zeroinitializer
82
+ ;
83
+ %add = sub nuw <2 x i16 > <i16 12 , i16 13 >, %a
84
+ %cond = call <2 x i16 > @llvm.usub.sat.v2i16 (<2 x i16 > %add , <2 x i16 > <i16 14 , i16 15 >)
85
+ ret <2 x i16 > %cond
86
+ }
87
+
88
+ ; negative tests this souldn't work
89
+ define i32 @usub_sat_C1_C2_without_nuw (i32 %a ){
90
+ ; CHECK-LABEL: @usub_sat_C1_C2_without_nuw(
91
+ ; CHECK-NEXT: [[ADD:%.*]] = sub i32 12, [[A:%.*]]
92
+ ; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[ADD]], i32 14)
93
+ ; CHECK-NEXT: ret i32 [[COND]]
94
+ ;
95
+ %add = sub i32 12 , %a
96
+ %cond = call i32 @llvm.usub.sat.i32 (i32 %add , i32 14 )
97
+ ret i32 %cond
98
+ }
99
+
11
100
; (a > b) ? a - b : 0 -> usub.sat(a, b)
12
101
13
102
define i64 @max_sub_ugt (i64 %a , i64 %b ) {
0 commit comments