11; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
22; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
33
4- define i1 @abs_int_min_is_not_poison (i32 %arg ) {
4+ define i1 @abs_int_min_is_not_poison (i32 noundef %arg ) {
55; CHECK-LABEL: define i1 @abs_int_min_is_not_poison(
6- ; CHECK-SAME: i32 [[ARG:%.*]]) {
6+ ; CHECK-SAME: i32 noundef [[ARG:%.*]]) {
77; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 false)
88; CHECK-NEXT: ret i1 true
99;
@@ -12,87 +12,149 @@ define i1 @abs_int_min_is_not_poison(i32 %arg) {
1212 ret i1 %cmp
1313}
1414
15- define i1 @abs_int_min_is_poison (i32 %arg ) {
15+ define i1 @abs_int_min_is_poison (i32 noundef %arg ) {
1616; CHECK-LABEL: define i1 @abs_int_min_is_poison(
17- ; CHECK-SAME: i32 [[ARG:%.*]]) {
17+ ; CHECK-SAME: i32 noundef [[ARG:%.*]]) {
1818; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 true)
19- ; CHECK-NEXT: ret i1 true
19+ ; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[ABS]], [[ARG]]
20+ ; CHECK-NEXT: ret i1 [[CMP]]
2021;
2122 %abs = tail call i32 @llvm.abs.i32 (i32 %arg , i1 true )
2223 %cmp = icmp sge i32 %abs , %arg
2324 ret i1 %cmp
2425}
2526
26- define i1 @abs_plus_one (i32 %arg ) {
27- ; CHECK-LABEL: define i1 @abs_plus_one (
28- ; CHECK-SAME: i32 [[ARG:%.*]]) {
29- ; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 true )
27+ define i1 @abs_plus_one_min_is_not_poison (i32 noundef %arg ) {
28+ ; CHECK-LABEL: define i1 @abs_plus_one_min_is_not_poison (
29+ ; CHECK-SAME: i32 noundef [[ARG:%.*]]) {
30+ ; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 false )
3031; CHECK-NEXT: [[ABS_PLUS_ONE:%.*]] = add nsw i32 [[ABS]], 1
3132; CHECK-NEXT: ret i1 true
3233;
33- %abs = tail call i32 @llvm.abs.i32 (i32 %arg , i1 true )
34+ %abs = tail call i32 @llvm.abs.i32 (i32 %arg , i1 false )
3435 %abs_plus_one = add nsw i32 %abs , 1
3536 %cmp = icmp sge i32 %abs_plus_one , %arg
3637 ret i1 %cmp
3738}
3839
39- define i1 @arg_minus_one_strict_less (i32 %arg ) {
40- ; CHECK-LABEL: define i1 @arg_minus_one_strict_less (
41- ; CHECK-SAME: i32 [[ARG:%.*]]) {
40+ define i1 @abs_plus_one_min_is_poison (i32 noundef %arg ) {
41+ ; CHECK-LABEL: define i1 @abs_plus_one_min_is_poison (
42+ ; CHECK-SAME: i32 noundef [[ARG:%.*]]) {
4243; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 true)
44+ ; CHECK-NEXT: [[ABS_PLUS_ONE:%.*]] = add nsw i32 [[ABS]], 1
45+ ; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[ABS_PLUS_ONE]], [[ARG]]
46+ ; CHECK-NEXT: ret i1 [[CMP]]
47+ ;
48+ %abs = tail call i32 @llvm.abs.i32 (i32 %arg , i1 true )
49+ %abs_plus_one = add nsw i32 %abs , 1
50+ %cmp = icmp sge i32 %abs_plus_one , %arg
51+ ret i1 %cmp
52+ }
53+
54+ define i1 @arg_minus_one_strict_less_min_is_not_poison (i32 noundef %arg ) {
55+ ; CHECK-LABEL: define i1 @arg_minus_one_strict_less_min_is_not_poison(
56+ ; CHECK-SAME: i32 noundef [[ARG:%.*]]) {
57+ ; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 false)
4358; CHECK-NEXT: [[ARG_MINUS_ONE:%.*]] = add nsw i32 [[ARG]], -1
4459; CHECK-NEXT: ret i1 true
4560;
46- %abs = tail call i32 @llvm.abs.i32 (i32 %arg , i1 true )
61+ %abs = tail call i32 @llvm.abs.i32 (i32 %arg , i1 false )
4762 %arg_minus_one = add nsw i32 %arg , -1
4863 %cmp = icmp slt i32 %arg_minus_one , %abs
4964 ret i1 %cmp
5065}
5166
52- define i1 @arg_minus_one_strict_greater (i32 %arg ) {
53- ; CHECK-LABEL: define i1 @arg_minus_one_strict_greater(
54- ; CHECK-SAME: i32 [[ARG:%.*]]) {
67+
68+ define i1 @arg_minus_one_strict_less_min_is_poison (i32 noundef %arg ) {
69+ ; CHECK-LABEL: define i1 @arg_minus_one_strict_less_min_is_poison(
70+ ; CHECK-SAME: i32 noundef [[ARG:%.*]]) {
5571; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 true)
5672; CHECK-NEXT: [[ARG_MINUS_ONE:%.*]] = add nsw i32 [[ARG]], -1
73+ ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[ARG_MINUS_ONE]], [[ABS]]
74+ ; CHECK-NEXT: ret i1 [[CMP]]
75+ ;
76+ %abs = tail call i32 @llvm.abs.i32 (i32 %arg , i1 true )
77+ %arg_minus_one = add nsw i32 %arg , -1
78+ %cmp = icmp slt i32 %arg_minus_one , %abs
79+ ret i1 %cmp
80+ }
81+
82+ define i1 @arg_minus_one_strict_greater_min_is_not_poison (i32 noundef %arg ) {
83+ ; CHECK-LABEL: define i1 @arg_minus_one_strict_greater_min_is_not_poison(
84+ ; CHECK-SAME: i32 noundef [[ARG:%.*]]) {
85+ ; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 false)
86+ ; CHECK-NEXT: [[ARG_MINUS_ONE:%.*]] = add nsw i32 [[ARG]], -1
5787; CHECK-NEXT: ret i1 false
88+ ;
89+ %abs = tail call i32 @llvm.abs.i32 (i32 %arg , i1 false )
90+ %arg_minus_one = add nsw i32 %arg , -1
91+ %cmp = icmp sgt i32 %arg_minus_one , %abs
92+ ret i1 %cmp
93+ }
94+
95+ define i1 @arg_minus_one_strict_greater_min_is_poison (i32 noundef %arg ) {
96+ ; CHECK-LABEL: define i1 @arg_minus_one_strict_greater_min_is_poison(
97+ ; CHECK-SAME: i32 noundef [[ARG:%.*]]) {
98+ ; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 true)
99+ ; CHECK-NEXT: [[ARG_MINUS_ONE:%.*]] = add nsw i32 [[ARG]], -1
100+ ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[ARG_MINUS_ONE]], [[ABS]]
101+ ; CHECK-NEXT: ret i1 [[CMP]]
58102;
59103 %abs = tail call i32 @llvm.abs.i32 (i32 %arg , i1 true )
60104 %arg_minus_one = add nsw i32 %arg , -1
61105 %cmp = icmp sgt i32 %arg_minus_one , %abs
62106 ret i1 %cmp
63107}
64108
65- define i1 @abs_plus_one_unsigned_greater_or_equal_nonnegative_arg (i32 %arg ) {
66- ; CHECK-LABEL: define i1 @abs_plus_one_unsigned_greater_or_equal_nonnegative_arg (
67- ; CHECK-SAME: i32 [[ARG:%.*]]) {
109+ define i1 @abs_plus_one_unsigned_greater_or_equal_nonnegative_arg_min_is_not_poison (i32 noundef %arg ) {
110+ ; CHECK-LABEL: define i1 @abs_plus_one_unsigned_greater_or_equal_nonnegative_arg_min_is_not_poison (
111+ ; CHECK-SAME: i32 noundef [[ARG:%.*]]) {
68112; CHECK-NEXT: [[CMP_ARG_NONNEGATIVE:%.*]] = icmp sge i32 [[ARG]], 0
69113; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_ARG_NONNEGATIVE]])
70- ; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 true )
114+ ; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 false )
71115; CHECK-NEXT: [[ABS_PLUS_ONE:%.*]] = add nuw i32 [[ABS]], 1
72116; CHECK-NEXT: ret i1 true
73117;
74118 %cmp_arg_nonnegative = icmp sge i32 %arg , 0
75119 call void @llvm.assume (i1 %cmp_arg_nonnegative )
76- %abs = tail call i32 @llvm.abs.i32 (i32 %arg , i1 true )
120+ %abs = tail call i32 @llvm.abs.i32 (i32 %arg , i1 false )
77121 %abs_plus_one = add nuw i32 %abs , 1
78122 %cmp = icmp uge i32 %abs_plus_one , %arg
79123 ret i1 %cmp
80124}
81125
82- define i1 @abs_plus_one_unsigned_greater_or_equal_cannot_be_simplified (i32 %arg ) {
83- ; CHECK-LABEL: define i1 @abs_plus_one_unsigned_greater_or_equal_cannot_be_simplified(
84- ; CHECK-SAME: i32 [[ARG:%.*]]) {
126+ define i1 @abs_plus_one_unsigned_greater_or_equal_nonnegative_arg_min_is_poison (i32 noundef %arg ) {
127+ ; CHECK-LABEL: define i1 @abs_plus_one_unsigned_greater_or_equal_nonnegative_arg_min_is_poison(
128+ ; CHECK-SAME: i32 noundef [[ARG:%.*]]) {
129+ ; CHECK-NEXT: [[CMP_ARG_NONNEGATIVE:%.*]] = icmp sge i32 [[ARG]], 0
130+ ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_ARG_NONNEGATIVE]])
85131; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 true)
86132; CHECK-NEXT: [[ABS_PLUS_ONE:%.*]] = add nuw i32 [[ABS]], 1
87133; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[ABS_PLUS_ONE]], [[ARG]]
88134; CHECK-NEXT: ret i1 [[CMP]]
89135;
136+ %cmp_arg_nonnegative = icmp sge i32 %arg , 0
137+ call void @llvm.assume (i1 %cmp_arg_nonnegative )
90138 %abs = tail call i32 @llvm.abs.i32 (i32 %arg , i1 true )
91139 %abs_plus_one = add nuw i32 %abs , 1
92140 %cmp = icmp uge i32 %abs_plus_one , %arg
93141 ret i1 %cmp
94142}
95143
144+ define i1 @abs_plus_one_unsigned_greater_or_equal_cannot_be_simplified (i32 noundef %arg ) {
145+ ; CHECK-LABEL: define i1 @abs_plus_one_unsigned_greater_or_equal_cannot_be_simplified(
146+ ; CHECK-SAME: i32 noundef [[ARG:%.*]]) {
147+ ; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 false)
148+ ; CHECK-NEXT: [[ABS_PLUS_ONE:%.*]] = add nuw i32 [[ABS]], 1
149+ ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[ABS_PLUS_ONE]], [[ARG]]
150+ ; CHECK-NEXT: ret i1 [[CMP]]
151+ ;
152+ %abs = tail call i32 @llvm.abs.i32 (i32 %arg , i1 false )
153+ %abs_plus_one = add nuw i32 %abs , 1
154+ %cmp = icmp uge i32 %abs_plus_one , %arg
155+ ret i1 %cmp
156+ }
157+
96158define i1 @abs_constant_negative_arg () {
97159; CHECK-LABEL: define i1 @abs_constant_negative_arg() {
98160; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 -3, i1 false)
@@ -114,9 +176,9 @@ define i1 @abs_constant_positive_arg() {
114176 ret i1 %cmp
115177}
116178
117- define i1 @abs_is_nonnegative_except_for_int_min_if_int_min_is_not_poison (i32 %arg ) {
179+ define i1 @abs_is_nonnegative_except_for_int_min_if_int_min_is_not_poison (i32 noundef %arg ) {
118180; CHECK-LABEL: define i1 @abs_is_nonnegative_except_for_int_min_if_int_min_is_not_poison(
119- ; CHECK-SAME: i32 [[ARG:%.*]]) {
181+ ; CHECK-SAME: i32 noundef [[ARG:%.*]]) {
120182; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 false)
121183; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[ABS]], 0
122184; CHECK-NEXT: ret i1 [[CMP]]
@@ -126,23 +188,36 @@ define i1 @abs_is_nonnegative_except_for_int_min_if_int_min_is_not_poison(i32 %a
126188 ret i1 %cmp
127189}
128190
129- define i1 @abs_is_not_strictly_positive (i32 %arg ) {
191+ define i1 @abs_is_not_strictly_positive (i32 noundef %arg ) {
130192; CHECK-LABEL: define i1 @abs_is_not_strictly_positive(
131- ; CHECK-SAME: i32 [[ARG:%.*]]) {
132- ; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 true )
193+ ; CHECK-SAME: i32 noundef [[ARG:%.*]]) {
194+ ; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 false )
133195; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[ABS]], 0
134196; CHECK-NEXT: ret i1 [[CMP]]
135197;
136- %abs = tail call i32 @llvm.abs.i32 (i32 %arg , i1 true )
198+ %abs = tail call i32 @llvm.abs.i32 (i32 %arg , i1 false )
137199 %cmp = icmp sgt i32 %abs , 0
138200 ret i1 %cmp
139201}
140202
141- define i1 @abs_is_nonnegative_int_min_is_poison (i32 %arg ) {
203+ define i1 @abs_is_nonnegative_int_min_is_not_poison (i32 noundef %arg ) {
204+ ; CHECK-LABEL: define i1 @abs_is_nonnegative_int_min_is_not_poison(
205+ ; CHECK-SAME: i32 noundef [[ARG:%.*]]) {
206+ ; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 false)
207+ ; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[ABS]], 0
208+ ; CHECK-NEXT: ret i1 [[CMP]]
209+ ;
210+ %abs = tail call i32 @llvm.abs.i32 (i32 %arg , i1 false )
211+ %cmp = icmp sge i32 %abs , 0
212+ ret i1 %cmp
213+ }
214+
215+ define i1 @abs_is_nonnegative_int_min_is_poison (i32 noundef %arg ) {
142216; CHECK-LABEL: define i1 @abs_is_nonnegative_int_min_is_poison(
143- ; CHECK-SAME: i32 [[ARG:%.*]]) {
217+ ; CHECK-SAME: i32 noundef [[ARG:%.*]]) {
144218; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 true)
145- ; CHECK-NEXT: ret i1 true
219+ ; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[ABS]], 0
220+ ; CHECK-NEXT: ret i1 [[CMP]]
146221;
147222 %abs = tail call i32 @llvm.abs.i32 (i32 %arg , i1 true )
148223 %cmp = icmp sge i32 %abs , 0
@@ -152,7 +227,8 @@ define i1 @abs_is_nonnegative_int_min_is_poison(i32 %arg) {
152227define i1 @abs_is_nonnegative_constant_arg () {
153228; CHECK-LABEL: define i1 @abs_is_nonnegative_constant_arg() {
154229; CHECK-NEXT: [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 -3, i1 true)
155- ; CHECK-NEXT: ret i1 true
230+ ; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[ABS]], 0
231+ ; CHECK-NEXT: ret i1 [[CMP]]
156232;
157233 %abs = tail call i32 @llvm.abs.i32 (i32 -3 , i1 true )
158234 %cmp = icmp sge i32 %abs , 0
0 commit comments