xref: /llvm-project/llvm/test/Transforms/ConstraintElimination/abs.ll (revision 4d8e849dfbf3ca1301f208a7286b31215d2a94db)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
2; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s
3
4define i1 @abs_int_min_is_not_poison(i32 %arg) {
5; CHECK-LABEL: define i1 @abs_int_min_is_not_poison(
6; CHECK-SAME: i32 [[ARG:%.*]]) {
7; CHECK-NEXT:    [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 false)
8; CHECK-NEXT:    ret i1 true
9;
10  %abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 false)
11  %cmp = icmp sge i32 %abs, %arg
12  ret i1 %cmp
13}
14
15define i1 @abs_int_min_is_poison(i32 %arg) {
16; CHECK-LABEL: define i1 @abs_int_min_is_poison(
17; CHECK-SAME: i32 [[ARG:%.*]]) {
18; CHECK-NEXT:    [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 true)
19; CHECK-NEXT:    ret i1 true
20;
21  %abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 true)
22  %cmp = icmp sge i32 %abs, %arg
23  ret i1 %cmp
24}
25
26define 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)
30; CHECK-NEXT:    [[ABS_PLUS_ONE:%.*]] = add nsw i32 [[ABS]], 1
31; CHECK-NEXT:    ret i1 true
32;
33  %abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 true)
34  %abs_plus_one = add nsw i32 %abs, 1
35  %cmp = icmp sge i32 %abs_plus_one, %arg
36  ret i1 %cmp
37}
38
39define i1 @arg_minus_one_strict_less(i32 %arg) {
40; CHECK-LABEL: define i1 @arg_minus_one_strict_less(
41; CHECK-SAME: i32 [[ARG:%.*]]) {
42; CHECK-NEXT:    [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 true)
43; CHECK-NEXT:    [[ARG_MINUS_ONE:%.*]] = add nsw i32 [[ARG]], -1
44; CHECK-NEXT:    ret i1 true
45;
46  %abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 true)
47  %arg_minus_one = add nsw i32 %arg, -1
48  %cmp = icmp slt i32 %arg_minus_one, %abs
49  ret i1 %cmp
50}
51
52define i1 @arg_minus_one_strict_greater(i32 %arg) {
53; CHECK-LABEL: define i1 @arg_minus_one_strict_greater(
54; CHECK-SAME: i32 [[ARG:%.*]]) {
55; CHECK-NEXT:    [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 true)
56; CHECK-NEXT:    [[ARG_MINUS_ONE:%.*]] = add nsw i32 [[ARG]], -1
57; CHECK-NEXT:    ret i1 false
58;
59  %abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 true)
60  %arg_minus_one = add nsw i32 %arg, -1
61  %cmp = icmp sgt i32 %arg_minus_one, %abs
62  ret i1 %cmp
63}
64
65define 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:%.*]]) {
68; CHECK-NEXT:    [[CMP_ARG_NONNEGATIVE:%.*]] = icmp sge i32 [[ARG]], 0
69; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_ARG_NONNEGATIVE]])
70; CHECK-NEXT:    [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 true)
71; CHECK-NEXT:    [[ABS_PLUS_ONE:%.*]] = add nuw i32 [[ABS]], 1
72; CHECK-NEXT:    ret i1 true
73;
74  %cmp_arg_nonnegative = icmp sge i32 %arg, 0
75  call void @llvm.assume(i1 %cmp_arg_nonnegative)
76  %abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 true)
77  %abs_plus_one = add nuw i32 %abs, 1
78  %cmp = icmp uge i32 %abs_plus_one, %arg
79  ret i1 %cmp
80}
81
82define 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:%.*]]) {
85; CHECK-NEXT:    [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 true)
86; CHECK-NEXT:    [[ABS_PLUS_ONE:%.*]] = add nuw i32 [[ABS]], 1
87; CHECK-NEXT:    [[CMP:%.*]] = icmp uge i32 [[ABS_PLUS_ONE]], [[ARG]]
88; CHECK-NEXT:    ret i1 [[CMP]]
89;
90  %abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 true)
91  %abs_plus_one = add nuw i32 %abs, 1
92  %cmp = icmp uge i32 %abs_plus_one, %arg
93  ret i1 %cmp
94}
95
96define i1 @abs_constant_negative_arg() {
97; CHECK-LABEL: define i1 @abs_constant_negative_arg() {
98; CHECK-NEXT:    [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 -3, i1 false)
99; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[ABS]], 3
100; CHECK-NEXT:    ret i1 [[CMP]]
101;
102  %abs = tail call i32 @llvm.abs.i32(i32 -3, i1 false)
103  %cmp = icmp sge i32 %abs, 3
104  ret i1 %cmp
105}
106
107define i1 @abs_constant_positive_arg() {
108; CHECK-LABEL: define i1 @abs_constant_positive_arg() {
109; CHECK-NEXT:    [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 3, i1 false)
110; CHECK-NEXT:    ret i1 true
111;
112  %abs = tail call i32 @llvm.abs.i32(i32 3, i1 false)
113  %cmp = icmp sge i32 %abs, 3
114  ret i1 %cmp
115}
116
117define i1 @abs_is_nonnegative_except_for_int_min_if_int_min_is_not_poison(i32 %arg) {
118; CHECK-LABEL: define i1 @abs_is_nonnegative_except_for_int_min_if_int_min_is_not_poison(
119; CHECK-SAME: i32 [[ARG:%.*]]) {
120; CHECK-NEXT:    [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 false)
121; CHECK-NEXT:    [[CMP:%.*]] = icmp sge i32 [[ABS]], 0
122; CHECK-NEXT:    ret i1 [[CMP]]
123;
124  %abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 false)
125  %cmp = icmp sge i32 %abs, 0
126  ret i1 %cmp
127}
128
129define i1 @abs_is_not_strictly_positive(i32 %arg) {
130; 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)
133; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[ABS]], 0
134; CHECK-NEXT:    ret i1 [[CMP]]
135;
136  %abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 true)
137  %cmp = icmp sgt i32 %abs, 0
138  ret i1 %cmp
139}
140
141define i1 @abs_is_nonnegative_int_min_is_poison(i32 %arg) {
142; CHECK-LABEL: define i1 @abs_is_nonnegative_int_min_is_poison(
143; CHECK-SAME: i32 [[ARG:%.*]]) {
144; CHECK-NEXT:    [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 [[ARG]], i1 true)
145; CHECK-NEXT:    ret i1 true
146;
147  %abs = tail call i32 @llvm.abs.i32(i32 %arg, i1 true)
148  %cmp = icmp sge i32 %abs, 0
149  ret i1 %cmp
150}
151
152define i1 @abs_is_nonnegative_constant_arg() {
153; CHECK-LABEL: define i1 @abs_is_nonnegative_constant_arg() {
154; CHECK-NEXT:    [[ABS:%.*]] = tail call i32 @llvm.abs.i32(i32 -3, i1 true)
155; CHECK-NEXT:    ret i1 true
156;
157  %abs = tail call i32 @llvm.abs.i32(i32 -3, i1 true)
158  %cmp = icmp sge i32 %abs, 0
159  ret i1 %cmp
160}
161
162declare i32 @llvm.abs.i32(i32, i1 immarg)
163declare void @llvm.assume(i1)
164