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