Home | History | Annotate | Download | only in InstCombine
      1 ; RUN: opt < %s -instcombine -S | FileCheck %s
      2 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
      3 target triple = "x86_64-unknown-linux-gnu"
      4 
      5 ; Function Attrs: nounwind uwtable
      6 define i32 @foo1(i32* %a) #0 {
      7 entry:
      8   %0 = load i32, i32* %a, align 4
      9 
     10 ; Check that the alignment has been upgraded and that the assume has not
     11 ; been removed:
     12 ; CHECK-LABEL: @foo1
     13 ; CHECK-DAG: load i32, i32* %a, align 32
     14 ; CHECK-DAG: call void @llvm.assume
     15 ; CHECK: ret i32
     16 
     17   %ptrint = ptrtoint i32* %a to i64
     18   %maskedptr = and i64 %ptrint, 31
     19   %maskcond = icmp eq i64 %maskedptr, 0
     20   tail call void @llvm.assume(i1 %maskcond)
     21 
     22   ret i32 %0
     23 }
     24 
     25 ; Function Attrs: nounwind uwtable
     26 define i32 @foo2(i32* %a) #0 {
     27 entry:
     28 ; Same check as in @foo1, but make sure it works if the assume is first too.
     29 ; CHECK-LABEL: @foo2
     30 ; CHECK-DAG: load i32, i32* %a, align 32
     31 ; CHECK-DAG: call void @llvm.assume
     32 ; CHECK: ret i32
     33 
     34   %ptrint = ptrtoint i32* %a to i64
     35   %maskedptr = and i64 %ptrint, 31
     36   %maskcond = icmp eq i64 %maskedptr, 0
     37   tail call void @llvm.assume(i1 %maskcond)
     38 
     39   %0 = load i32, i32* %a, align 4
     40   ret i32 %0
     41 }
     42 
     43 ; Function Attrs: nounwind
     44 declare void @llvm.assume(i1) #1
     45 
     46 define i32 @simple(i32 %a) #1 {
     47 entry:
     48 
     49 ; CHECK-LABEL: @simple
     50 ; CHECK: call void @llvm.assume
     51 ; CHECK: ret i32 4
     52 
     53   %cmp = icmp eq i32 %a, 4
     54   tail call void @llvm.assume(i1 %cmp)
     55   ret i32 %a
     56 }
     57 
     58 ; Function Attrs: nounwind uwtable
     59 define i32 @can1(i1 %a, i1 %b, i1 %c) {
     60 entry:
     61   %and1 = and i1 %a, %b
     62   %and  = and i1 %and1, %c
     63   tail call void @llvm.assume(i1 %and)
     64 
     65 ; CHECK-LABEL: @can1
     66 ; CHECK: call void @llvm.assume(i1 %a)
     67 ; CHECK: call void @llvm.assume(i1 %b)
     68 ; CHECK: call void @llvm.assume(i1 %c)
     69 ; CHECK: ret i32
     70 
     71   ret i32 5
     72 }
     73 
     74 ; Function Attrs: nounwind uwtable
     75 define i32 @can2(i1 %a, i1 %b, i1 %c) {
     76 entry:
     77   %v = or i1 %a, %b
     78   %w = xor i1 %v, 1
     79   tail call void @llvm.assume(i1 %w)
     80 
     81 ; CHECK-LABEL: @can2
     82 ; CHECK: %[[V1:[^ ]+]] = xor i1 %a, true
     83 ; CHECK: call void @llvm.assume(i1 %[[V1]])
     84 ; CHECK: %[[V2:[^ ]+]] = xor i1 %b, true
     85 ; CHECK: call void @llvm.assume(i1 %[[V2]])
     86 ; CHECK: ret i32
     87 
     88   ret i32 5
     89 }
     90 
     91 define i32 @bar1(i32 %a) #0 {
     92 entry:
     93   %and1 = and i32 %a, 3
     94 
     95 ; CHECK-LABEL: @bar1
     96 ; CHECK: call void @llvm.assume
     97 ; CHECK: ret i32 1
     98 
     99   %and = and i32 %a, 7
    100   %cmp = icmp eq i32 %and, 1
    101   tail call void @llvm.assume(i1 %cmp)
    102 
    103   ret i32 %and1
    104 }
    105 
    106 ; Function Attrs: nounwind uwtable
    107 define i32 @bar2(i32 %a) #0 {
    108 entry:
    109 ; CHECK-LABEL: @bar2
    110 ; CHECK: call void @llvm.assume
    111 ; CHECK: ret i32 1
    112 
    113   %and = and i32 %a, 7
    114   %cmp = icmp eq i32 %and, 1
    115   tail call void @llvm.assume(i1 %cmp)
    116 
    117   %and1 = and i32 %a, 3
    118   ret i32 %and1
    119 }
    120 
    121 ; Function Attrs: nounwind uwtable
    122 define i32 @bar3(i32 %a, i1 %x, i1 %y) #0 {
    123 entry:
    124   %and1 = and i32 %a, 3
    125 
    126 ; Don't be fooled by other assumes around.
    127 ; CHECK-LABEL: @bar3
    128 ; CHECK: call void @llvm.assume
    129 ; CHECK: ret i32 1
    130 
    131   tail call void @llvm.assume(i1 %x)
    132 
    133   %and = and i32 %a, 7
    134   %cmp = icmp eq i32 %and, 1
    135   tail call void @llvm.assume(i1 %cmp)
    136 
    137   tail call void @llvm.assume(i1 %y)
    138 
    139   ret i32 %and1
    140 }
    141 
    142 ; Function Attrs: nounwind uwtable
    143 define i32 @bar4(i32 %a, i32 %b) {
    144 entry:
    145   %and1 = and i32 %b, 3
    146 
    147 ; CHECK-LABEL: @bar4
    148 ; CHECK: call void @llvm.assume
    149 ; CHECK: call void @llvm.assume
    150 ; CHECK: ret i32 1
    151 
    152   %and = and i32 %a, 7
    153   %cmp = icmp eq i32 %and, 1
    154   tail call void @llvm.assume(i1 %cmp)
    155 
    156   %cmp2 = icmp eq i32 %a, %b
    157   tail call void @llvm.assume(i1 %cmp2)
    158 
    159   ret i32 %and1
    160 }
    161 
    162 define i32 @icmp1(i32 %a) #0 {
    163 entry:
    164   %cmp = icmp sgt i32 %a, 5
    165   tail call void @llvm.assume(i1 %cmp)
    166   %conv = zext i1 %cmp to i32
    167   ret i32 %conv
    168 
    169 ; CHECK-LABEL: @icmp1
    170 ; CHECK: call void @llvm.assume
    171 ; CHECK: ret i32 1
    172 
    173 }
    174 
    175 ; Function Attrs: nounwind uwtable
    176 define i32 @icmp2(i32 %a) #0 {
    177 entry:
    178   %cmp = icmp sgt i32 %a, 5
    179   tail call void @llvm.assume(i1 %cmp)
    180   %0 = zext i1 %cmp to i32
    181   %lnot.ext = xor i32 %0, 1
    182   ret i32 %lnot.ext
    183 
    184 ; CHECK-LABEL: @icmp2
    185 ; CHECK: call void @llvm.assume
    186 ; CHECK: ret i32 0
    187 }
    188 
    189 declare void @escape(i32* %a)
    190 
    191 ; Do we canonicalize a nonnull assumption on a load into
    192 ; metadata form?
    193 define i1 @nonnull1(i32** %a) {
    194 entry:
    195   %load = load i32*, i32** %a
    196   %cmp = icmp ne i32* %load, null
    197   tail call void @llvm.assume(i1 %cmp)
    198   tail call void @escape(i32* %load)
    199   %rval = icmp eq i32* %load, null
    200   ret i1 %rval
    201 
    202 ; CHECK-LABEL: @nonnull1
    203 ; CHECK: !nonnull
    204 ; CHECK-NOT: call void @llvm.assume
    205 ; CHECK: ret i1 false
    206 }
    207 
    208 ; Make sure the above canonicalization applies only
    209 ; to pointer types.  Doing otherwise would be illegal.
    210 define i1 @nonnull2(i32* %a) {
    211 entry:
    212   %load = load i32, i32* %a
    213   %cmp = icmp ne i32 %load, 0
    214   tail call void @llvm.assume(i1 %cmp)
    215   %rval = icmp eq i32 %load, 0
    216   ret i1 %rval
    217 
    218 ; CHECK-LABEL: @nonnull2
    219 ; CHECK-NOT: !nonnull
    220 ; CHECK: call void @llvm.assume
    221 }
    222 
    223 ; Make sure the above canonicalization does not trigger
    224 ; if the assume is control dependent on something else
    225 define i1 @nonnull3(i32** %a, i1 %control) {
    226 entry:
    227   %load = load i32*, i32** %a
    228   %cmp = icmp ne i32* %load, null
    229   br i1 %control, label %taken, label %not_taken
    230 taken:
    231   tail call void @llvm.assume(i1 %cmp)
    232   %rval = icmp eq i32* %load, null
    233   ret i1 %rval
    234 not_taken:
    235   ret i1 true
    236 
    237 ; CHECK-LABEL: @nonnull3
    238 ; CHECK-NOT: !nonnull
    239 ; CHECK: call void @llvm.assume
    240 }
    241 
    242 ; Make sure the above canonicalization does not trigger
    243 ; if the path from the load to the assume is potentially 
    244 ; interrupted by an exception being thrown
    245 define i1 @nonnull4(i32** %a) {
    246 entry:
    247   %load = load i32*, i32** %a
    248   ;; This call may throw!
    249   tail call void @escape(i32* %load)
    250   %cmp = icmp ne i32* %load, null
    251   tail call void @llvm.assume(i1 %cmp)
    252   %rval = icmp eq i32* %load, null
    253   ret i1 %rval
    254 
    255 ; CHECK-LABEL: @nonnull4
    256 ; CHECK-NOT: !nonnull
    257 ; CHECK: call void @llvm.assume
    258 }
    259 
    260 
    261 
    262 
    263 attributes #0 = { nounwind uwtable }
    264 attributes #1 = { nounwind }
    265 
    266