1 ; RUN: opt < %s -instcombine -S | FileCheck %s
2 ; These should be InstSimplify checks, but most of the code
3 ; is currently only in InstCombine. TODO: move supporting code
5 ; Definitely out of range
6 define i1 @test_nonzero(i32* nocapture readonly %arg) {
7 ; CHECK-LABEL:test_nonzero
9 %val = load i32, i32* %arg, !range !0
10 %rval = icmp ne i32 %val, 0
13 define i1 @test_nonzero2(i32* nocapture readonly %arg) {
14 ; CHECK-LABEL:test_nonzero2
16 %val = load i32, i32* %arg, !range !0
17 %rval = icmp eq i32 %val, 0
21 ; Potentially in range
22 define i1 @test_nonzero3(i32* nocapture readonly %arg) {
23 ; CHECK-LABEL: test_nonzero3
24 ; Check that this does not trigger - it wouldn't be legal
26 %val = load i32, i32* %arg, !range !1
27 %rval = icmp ne i32 %val, 0
32 define i1 @test_nonzero4(i8* nocapture readonly %arg) {
33 ; CHECK-LABEL: test_nonzero4
35 %val = load i8, i8* %arg, !range !2
36 %rval = icmp ne i8 %val, 0
40 define i1 @test_nonzero5(i8* nocapture readonly %arg) {
41 ; CHECK-LABEL: test_nonzero5
43 %val = load i8, i8* %arg, !range !2
44 %rval = icmp ugt i8 %val, 0
48 ; Cheaper checks (most values in range meet requirements)
49 define i1 @test_nonzero6(i8* %argw) {
50 ; CHECK-LABEL: test_nonzero6
51 ; CHECK: icmp ne i8 %val, 0
52 %val = load i8, i8* %argw, !range !3
53 %rval = icmp sgt i8 %val, 0
57 ; Constant not in range, should return true.
58 define i1 @test_not_in_range(i32* nocapture readonly %arg) {
59 ; CHECK-LABEL: test_not_in_range
61 %val = load i32, i32* %arg, !range !0
62 %rval = icmp ne i32 %val, 6
66 ; Constant in range, can not fold.
67 define i1 @test_in_range(i32* nocapture readonly %arg) {
68 ; CHECK-LABEL: test_in_range
69 ; CHECK: icmp ne i32 %val, 3
70 %val = load i32, i32* %arg, !range !0
71 %rval = icmp ne i32 %val, 3
75 ; Values in range greater than constant.
76 define i1 @test_range_sgt_constant(i32* nocapture readonly %arg) {
77 ; CHECK-LABEL: test_range_sgt_constant
79 %val = load i32, i32* %arg, !range !0
80 %rval = icmp sgt i32 %val, 0
84 ; Values in range less than constant.
85 define i1 @test_range_slt_constant(i32* nocapture readonly %arg) {
86 ; CHECK-LABEL: test_range_slt_constant
88 %val = load i32, i32* %arg, !range !0
89 %rval = icmp sgt i32 %val, 6
93 ; Values in union of multiple sub ranges not equal to constant.
94 define i1 @test_multi_range1(i32* nocapture readonly %arg) {
95 ; CHECK-LABEL: test_multi_range1
97 %val = load i32, i32* %arg, !range !4
98 %rval = icmp ne i32 %val, 0
102 ; Values in multiple sub ranges not equal to constant, but in
103 ; union of sub ranges could possibly equal to constant. This
104 ; in theory could also be folded and might be implemented in
105 ; the future if shown profitable in practice.
106 define i1 @test_multi_range2(i32* nocapture readonly %arg) {
107 ; CHECK-LABEL: test_multi_range2
108 ; CHECK: icmp ne i32 %val, 7
109 %val = load i32, i32* %arg, !range !4
110 %rval = icmp ne i32 %val, 7
114 ; Values' ranges overlap each other, so it can not be simplified.
115 define i1 @test_two_ranges(i32* nocapture readonly %arg1, i32* nocapture readonly %arg2) {
116 ; CHECK-LABEL: test_two_ranges
117 ; CHECK: icmp ult i32 %val2, %val1
118 %val1 = load i32, i32* %arg1, !range !5
119 %val2 = load i32, i32* %arg2, !range !6
120 %rval = icmp ult i32 %val2, %val1
124 ; Values' ranges do not overlap each other, so it can simplified to false.
125 define i1 @test_two_ranges2(i32* nocapture readonly %arg1, i32* nocapture readonly %arg2) {
126 ; CHECK-LABEL: test_two_ranges2
127 ; CHECK: ret i1 false
128 %val1 = load i32, i32* %arg1, !range !0
129 %val2 = load i32, i32* %arg2, !range !6
130 %rval = icmp ult i32 %val2, %val1
134 ; Values' ranges do not overlap each other, so it can simplified to true.
135 define i1 @test_two_ranges3(i32* nocapture readonly %arg1, i32* nocapture readonly %arg2) {
136 ; CHECK-LABEL: test_two_ranges3
138 %val1 = load i32, i32* %arg1, !range !0
139 %val2 = load i32, i32* %arg2, !range !6
140 %rval = icmp ugt i32 %val2, %val1
148 !4 = !{i32 1, i32 6, i32 8, i32 10}
149 !5 = !{i32 5, i32 10}
150 !6 = !{i32 8, i32 16}