Home | History | Annotate | Download | only in InstCombine
      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
      4 
      5 ; Definitely out of range
      6 define i1 @test_nonzero(i32* nocapture readonly %arg) {
      7 ; CHECK-LABEL:test_nonzero
      8 ; CHECK: ret i1 true
      9   %val = load i32, i32* %arg, !range !0
     10   %rval = icmp ne i32 %val, 0
     11   ret i1 %rval
     12 }
     13 define i1 @test_nonzero2(i32* nocapture readonly %arg) {
     14 ; CHECK-LABEL:test_nonzero2
     15 ; CHECK: ret i1 false
     16   %val = load i32, i32* %arg, !range !0
     17   %rval = icmp eq i32 %val, 0
     18   ret i1 %rval
     19 }
     20 
     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
     25 ; CHECK: icmp
     26   %val = load i32, i32* %arg, !range !1
     27   %rval = icmp ne i32 %val, 0
     28   ret i1 %rval
     29 }
     30 
     31 ; Definitely in range
     32 define i1 @test_nonzero4(i8* nocapture readonly %arg) {
     33 ; CHECK-LABEL: test_nonzero4
     34 ; CHECK: ret i1 false
     35   %val = load i8, i8* %arg, !range !2
     36   %rval = icmp ne i8 %val, 0
     37   ret i1 %rval
     38 }
     39 
     40 define i1 @test_nonzero5(i8* nocapture readonly %arg) {
     41 ; CHECK-LABEL: test_nonzero5
     42 ; CHECK: ret i1 false
     43   %val = load i8, i8* %arg, !range !2
     44   %rval = icmp ugt i8 %val, 0
     45   ret i1 %rval
     46 }
     47 
     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
     54   ret i1 %rval
     55 }
     56 
     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
     60 ; CHECK: ret i1 true
     61   %val = load i32, i32* %arg, !range !0
     62   %rval = icmp ne i32 %val, 6
     63   ret i1 %rval
     64 }
     65 
     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
     72   ret i1 %rval
     73 }
     74 
     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
     78 ; CHECK: ret i1 true
     79   %val = load i32, i32* %arg, !range !0
     80   %rval = icmp sgt i32 %val, 0
     81   ret i1 %rval
     82 }
     83 
     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
     87 ; CHECK: ret i1 false
     88   %val = load i32, i32* %arg, !range !0
     89   %rval = icmp sgt i32 %val, 6
     90   ret i1 %rval
     91 }
     92 
     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
     96 ; CHECK: ret i1 true
     97   %val = load i32, i32* %arg, !range !4
     98   %rval = icmp ne i32 %val, 0
     99   ret i1 %rval
    100 }
    101 
    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
    111   ret i1 %rval
    112 }
    113 
    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
    121   ret i1 %rval
    122 }
    123 
    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
    131   ret i1 %rval
    132 }
    133 
    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
    137 ; CHECK: ret i1 true
    138   %val1 = load i32, i32* %arg1, !range !0
    139   %val2 = load i32, i32* %arg2, !range !6
    140   %rval = icmp ugt i32 %val2, %val1
    141   ret i1 %rval
    142 }
    143 
    144 !0 = !{i32 1, i32 6} 
    145 !1 = !{i32 0, i32 6} 
    146 !2 = !{i8 0, i8 1} 
    147 !3 = !{i8 0, i8 6} 
    148 !4 = !{i32 1, i32 6, i32 8, i32 10}
    149 !5 = !{i32 5, i32 10} 
    150 !6 = !{i32 8, i32 16} 
    151