xref: /aosp_15_r20/external/llvm/test/Transforms/InstCombine/icmp-range.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: opt < %s -instcombine -S | FileCheck %s
2*9880d681SAndroid Build Coastguard Worker; These should be InstSimplify checks, but most of the code
3*9880d681SAndroid Build Coastguard Worker; is currently only in InstCombine.  TODO: move supporting code
4*9880d681SAndroid Build Coastguard Worker
5*9880d681SAndroid Build Coastguard Worker; Definitely out of range
6*9880d681SAndroid Build Coastguard Workerdefine i1 @test_nonzero(i32* nocapture readonly %arg) {
7*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL:test_nonzero
8*9880d681SAndroid Build Coastguard Worker; CHECK: ret i1 true
9*9880d681SAndroid Build Coastguard Worker  %val = load i32, i32* %arg, !range !0
10*9880d681SAndroid Build Coastguard Worker  %rval = icmp ne i32 %val, 0
11*9880d681SAndroid Build Coastguard Worker  ret i1 %rval
12*9880d681SAndroid Build Coastguard Worker}
13*9880d681SAndroid Build Coastguard Workerdefine i1 @test_nonzero2(i32* nocapture readonly %arg) {
14*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL:test_nonzero2
15*9880d681SAndroid Build Coastguard Worker; CHECK: ret i1 false
16*9880d681SAndroid Build Coastguard Worker  %val = load i32, i32* %arg, !range !0
17*9880d681SAndroid Build Coastguard Worker  %rval = icmp eq i32 %val, 0
18*9880d681SAndroid Build Coastguard Worker  ret i1 %rval
19*9880d681SAndroid Build Coastguard Worker}
20*9880d681SAndroid Build Coastguard Worker
21*9880d681SAndroid Build Coastguard Worker; Potentially in range
22*9880d681SAndroid Build Coastguard Workerdefine i1 @test_nonzero3(i32* nocapture readonly %arg) {
23*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_nonzero3
24*9880d681SAndroid Build Coastguard Worker; Check that this does not trigger - it wouldn't be legal
25*9880d681SAndroid Build Coastguard Worker; CHECK: icmp
26*9880d681SAndroid Build Coastguard Worker  %val = load i32, i32* %arg, !range !1
27*9880d681SAndroid Build Coastguard Worker  %rval = icmp ne i32 %val, 0
28*9880d681SAndroid Build Coastguard Worker  ret i1 %rval
29*9880d681SAndroid Build Coastguard Worker}
30*9880d681SAndroid Build Coastguard Worker
31*9880d681SAndroid Build Coastguard Worker; Definitely in range
32*9880d681SAndroid Build Coastguard Workerdefine i1 @test_nonzero4(i8* nocapture readonly %arg) {
33*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_nonzero4
34*9880d681SAndroid Build Coastguard Worker; CHECK: ret i1 false
35*9880d681SAndroid Build Coastguard Worker  %val = load i8, i8* %arg, !range !2
36*9880d681SAndroid Build Coastguard Worker  %rval = icmp ne i8 %val, 0
37*9880d681SAndroid Build Coastguard Worker  ret i1 %rval
38*9880d681SAndroid Build Coastguard Worker}
39*9880d681SAndroid Build Coastguard Worker
40*9880d681SAndroid Build Coastguard Workerdefine i1 @test_nonzero5(i8* nocapture readonly %arg) {
41*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_nonzero5
42*9880d681SAndroid Build Coastguard Worker; CHECK: ret i1 false
43*9880d681SAndroid Build Coastguard Worker  %val = load i8, i8* %arg, !range !2
44*9880d681SAndroid Build Coastguard Worker  %rval = icmp ugt i8 %val, 0
45*9880d681SAndroid Build Coastguard Worker  ret i1 %rval
46*9880d681SAndroid Build Coastguard Worker}
47*9880d681SAndroid Build Coastguard Worker
48*9880d681SAndroid Build Coastguard Worker; Cheaper checks (most values in range meet requirements)
49*9880d681SAndroid Build Coastguard Workerdefine i1 @test_nonzero6(i8* %argw) {
50*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_nonzero6
51*9880d681SAndroid Build Coastguard Worker; CHECK: icmp ne i8 %val, 0
52*9880d681SAndroid Build Coastguard Worker  %val = load i8, i8* %argw, !range !3
53*9880d681SAndroid Build Coastguard Worker  %rval = icmp sgt i8 %val, 0
54*9880d681SAndroid Build Coastguard Worker  ret i1 %rval
55*9880d681SAndroid Build Coastguard Worker}
56*9880d681SAndroid Build Coastguard Worker
57*9880d681SAndroid Build Coastguard Worker; Constant not in range, should return true.
58*9880d681SAndroid Build Coastguard Workerdefine i1 @test_not_in_range(i32* nocapture readonly %arg) {
59*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_not_in_range
60*9880d681SAndroid Build Coastguard Worker; CHECK: ret i1 true
61*9880d681SAndroid Build Coastguard Worker  %val = load i32, i32* %arg, !range !0
62*9880d681SAndroid Build Coastguard Worker  %rval = icmp ne i32 %val, 6
63*9880d681SAndroid Build Coastguard Worker  ret i1 %rval
64*9880d681SAndroid Build Coastguard Worker}
65*9880d681SAndroid Build Coastguard Worker
66*9880d681SAndroid Build Coastguard Worker; Constant in range, can not fold.
67*9880d681SAndroid Build Coastguard Workerdefine i1 @test_in_range(i32* nocapture readonly %arg) {
68*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_in_range
69*9880d681SAndroid Build Coastguard Worker; CHECK: icmp ne i32 %val, 3
70*9880d681SAndroid Build Coastguard Worker  %val = load i32, i32* %arg, !range !0
71*9880d681SAndroid Build Coastguard Worker  %rval = icmp ne i32 %val, 3
72*9880d681SAndroid Build Coastguard Worker  ret i1 %rval
73*9880d681SAndroid Build Coastguard Worker}
74*9880d681SAndroid Build Coastguard Worker
75*9880d681SAndroid Build Coastguard Worker; Values in range greater than constant.
76*9880d681SAndroid Build Coastguard Workerdefine i1 @test_range_sgt_constant(i32* nocapture readonly %arg) {
77*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_range_sgt_constant
78*9880d681SAndroid Build Coastguard Worker; CHECK: ret i1 true
79*9880d681SAndroid Build Coastguard Worker  %val = load i32, i32* %arg, !range !0
80*9880d681SAndroid Build Coastguard Worker  %rval = icmp sgt i32 %val, 0
81*9880d681SAndroid Build Coastguard Worker  ret i1 %rval
82*9880d681SAndroid Build Coastguard Worker}
83*9880d681SAndroid Build Coastguard Worker
84*9880d681SAndroid Build Coastguard Worker; Values in range less than constant.
85*9880d681SAndroid Build Coastguard Workerdefine i1 @test_range_slt_constant(i32* nocapture readonly %arg) {
86*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_range_slt_constant
87*9880d681SAndroid Build Coastguard Worker; CHECK: ret i1 false
88*9880d681SAndroid Build Coastguard Worker  %val = load i32, i32* %arg, !range !0
89*9880d681SAndroid Build Coastguard Worker  %rval = icmp sgt i32 %val, 6
90*9880d681SAndroid Build Coastguard Worker  ret i1 %rval
91*9880d681SAndroid Build Coastguard Worker}
92*9880d681SAndroid Build Coastguard Worker
93*9880d681SAndroid Build Coastguard Worker; Values in union of multiple sub ranges not equal to constant.
94*9880d681SAndroid Build Coastguard Workerdefine i1 @test_multi_range1(i32* nocapture readonly %arg) {
95*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_multi_range1
96*9880d681SAndroid Build Coastguard Worker; CHECK: ret i1 true
97*9880d681SAndroid Build Coastguard Worker  %val = load i32, i32* %arg, !range !4
98*9880d681SAndroid Build Coastguard Worker  %rval = icmp ne i32 %val, 0
99*9880d681SAndroid Build Coastguard Worker  ret i1 %rval
100*9880d681SAndroid Build Coastguard Worker}
101*9880d681SAndroid Build Coastguard Worker
102*9880d681SAndroid Build Coastguard Worker; Values in multiple sub ranges not equal to constant, but in
103*9880d681SAndroid Build Coastguard Worker; union of sub ranges could possibly equal to constant. This
104*9880d681SAndroid Build Coastguard Worker; in theory could also be folded and might be implemented in
105*9880d681SAndroid Build Coastguard Worker; the future if shown profitable in practice.
106*9880d681SAndroid Build Coastguard Workerdefine i1 @test_multi_range2(i32* nocapture readonly %arg) {
107*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_multi_range2
108*9880d681SAndroid Build Coastguard Worker; CHECK: icmp ne i32 %val, 7
109*9880d681SAndroid Build Coastguard Worker  %val = load i32, i32* %arg, !range !4
110*9880d681SAndroid Build Coastguard Worker  %rval = icmp ne i32 %val, 7
111*9880d681SAndroid Build Coastguard Worker  ret i1 %rval
112*9880d681SAndroid Build Coastguard Worker}
113*9880d681SAndroid Build Coastguard Worker
114*9880d681SAndroid Build Coastguard Worker; Values' ranges overlap each other, so it can not be simplified.
115*9880d681SAndroid Build Coastguard Workerdefine i1 @test_two_ranges(i32* nocapture readonly %arg1, i32* nocapture readonly %arg2) {
116*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_two_ranges
117*9880d681SAndroid Build Coastguard Worker; CHECK: icmp ult i32 %val2, %val1
118*9880d681SAndroid Build Coastguard Worker  %val1 = load i32, i32* %arg1, !range !5
119*9880d681SAndroid Build Coastguard Worker  %val2 = load i32, i32* %arg2, !range !6
120*9880d681SAndroid Build Coastguard Worker  %rval = icmp ult i32 %val2, %val1
121*9880d681SAndroid Build Coastguard Worker  ret i1 %rval
122*9880d681SAndroid Build Coastguard Worker}
123*9880d681SAndroid Build Coastguard Worker
124*9880d681SAndroid Build Coastguard Worker; Values' ranges do not overlap each other, so it can simplified to false.
125*9880d681SAndroid Build Coastguard Workerdefine i1 @test_two_ranges2(i32* nocapture readonly %arg1, i32* nocapture readonly %arg2) {
126*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_two_ranges2
127*9880d681SAndroid Build Coastguard Worker; CHECK: ret i1 false
128*9880d681SAndroid Build Coastguard Worker  %val1 = load i32, i32* %arg1, !range !0
129*9880d681SAndroid Build Coastguard Worker  %val2 = load i32, i32* %arg2, !range !6
130*9880d681SAndroid Build Coastguard Worker  %rval = icmp ult i32 %val2, %val1
131*9880d681SAndroid Build Coastguard Worker  ret i1 %rval
132*9880d681SAndroid Build Coastguard Worker}
133*9880d681SAndroid Build Coastguard Worker
134*9880d681SAndroid Build Coastguard Worker; Values' ranges do not overlap each other, so it can simplified to true.
135*9880d681SAndroid Build Coastguard Workerdefine i1 @test_two_ranges3(i32* nocapture readonly %arg1, i32* nocapture readonly %arg2) {
136*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test_two_ranges3
137*9880d681SAndroid Build Coastguard Worker; CHECK: ret i1 true
138*9880d681SAndroid Build Coastguard Worker  %val1 = load i32, i32* %arg1, !range !0
139*9880d681SAndroid Build Coastguard Worker  %val2 = load i32, i32* %arg2, !range !6
140*9880d681SAndroid Build Coastguard Worker  %rval = icmp ugt i32 %val2, %val1
141*9880d681SAndroid Build Coastguard Worker  ret i1 %rval
142*9880d681SAndroid Build Coastguard Worker}
143*9880d681SAndroid Build Coastguard Worker
144*9880d681SAndroid Build Coastguard Worker!0 = !{i32 1, i32 6}
145*9880d681SAndroid Build Coastguard Worker!1 = !{i32 0, i32 6}
146*9880d681SAndroid Build Coastguard Worker!2 = !{i8 0, i8 1}
147*9880d681SAndroid Build Coastguard Worker!3 = !{i8 0, i8 6}
148*9880d681SAndroid Build Coastguard Worker!4 = !{i32 1, i32 6, i32 8, i32 10}
149*9880d681SAndroid Build Coastguard Worker!5 = !{i32 5, i32 10}
150*9880d681SAndroid Build Coastguard Worker!6 = !{i32 8, i32 16}
151