Home | History | Annotate | Download | only in LICM
      1 ; RUN: opt -S -licm < %s | FileCheck %s
      2 
      3 ; UDiv is safe to speculate if the denominator is known non-zero.
      4 
      5 ; CHECK-LABEL: @safe_udiv(
      6 ; CHECK:      %div = udiv i64 %x, 2
      7 ; CHECK-NEXT: br label %for.body
      8 
      9 define void @safe_udiv(i64 %x, i64 %m, i64 %n, i32* %p, i64* %q) nounwind {
     10 entry:
     11   br label %for.body
     12 
     13 for.body:                                         ; preds = %entry, %for.inc
     14   %i.02 = phi i64 [ %inc, %for.inc ], [ 0, %entry ]
     15   %arrayidx = getelementptr inbounds i32, i32* %p, i64 %i.02
     16   %0 = load i32, i32* %arrayidx, align 4
     17   %tobool = icmp eq i32 %0, 0
     18   br i1 %tobool, label %for.inc, label %if.then
     19 
     20 if.then:                                          ; preds = %for.body
     21   %div = udiv i64 %x, 2
     22   %arrayidx1 = getelementptr inbounds i64, i64* %q, i64 %i.02
     23   store i64 %div, i64* %arrayidx1, align 8
     24   br label %for.inc
     25 
     26 for.inc:                                          ; preds = %if.then, %for.body
     27   %inc = add i64 %i.02, 1
     28   %cmp = icmp slt i64 %inc, %n
     29   br i1 %cmp, label %for.body, label %for.end
     30 
     31 for.end:                                          ; preds = %for.inc, %entry
     32   ret void
     33 }
     34 
     35 ; UDiv is unsafe to speculate if the denominator is not known non-zero.
     36 
     37 ; CHECK-LABEL: @unsafe_udiv(
     38 ; CHECK-NOT:  udiv
     39 ; CHECK: for.body:
     40 
     41 define void @unsafe_udiv(i64 %x, i64 %m, i64 %n, i32* %p, i64* %q) nounwind {
     42 entry:
     43   br label %for.body
     44 
     45 for.body:                                         ; preds = %entry, %for.inc
     46   %i.02 = phi i64 [ %inc, %for.inc ], [ 0, %entry ]
     47   %arrayidx = getelementptr inbounds i32, i32* %p, i64 %i.02
     48   %0 = load i32, i32* %arrayidx, align 4
     49   %tobool = icmp eq i32 %0, 0
     50   br i1 %tobool, label %for.inc, label %if.then
     51 
     52 if.then:                                          ; preds = %for.body
     53   %div = udiv i64 %x, %m
     54   %arrayidx1 = getelementptr inbounds i64, i64* %q, i64 %i.02
     55   store i64 %div, i64* %arrayidx1, align 8
     56   br label %for.inc
     57 
     58 for.inc:                                          ; preds = %if.then, %for.body
     59   %inc = add i64 %i.02, 1
     60   %cmp = icmp slt i64 %inc, %n
     61   br i1 %cmp, label %for.body, label %for.end
     62 
     63 for.end:                                          ; preds = %for.inc, %entry
     64   ret void
     65 }
     66 
     67 ; SDiv is safe to speculate if the denominator is known non-zero and
     68 ; known to have at least one zero bit.
     69 
     70 ; CHECK-LABEL: @safe_sdiv(
     71 ; CHECK:      %div = sdiv i64 %x, 2
     72 ; CHECK-NEXT: br label %for.body
     73 
     74 define void @safe_sdiv(i64 %x, i64 %m, i64 %n, i32* %p, i64* %q) nounwind {
     75 entry:
     76   %and = and i64 %m, -3
     77   br label %for.body
     78 
     79 for.body:                                         ; preds = %entry, %for.inc
     80   %i.02 = phi i64 [ %inc, %for.inc ], [ 0, %entry ]
     81   %arrayidx = getelementptr inbounds i32, i32* %p, i64 %i.02
     82   %0 = load i32, i32* %arrayidx, align 4
     83   %tobool = icmp eq i32 %0, 0
     84   br i1 %tobool, label %for.inc, label %if.then
     85 
     86 if.then:                                          ; preds = %for.body
     87   %div = sdiv i64 %x, 2
     88   %arrayidx1 = getelementptr inbounds i64, i64* %q, i64 %i.02
     89   store i64 %div, i64* %arrayidx1, align 8
     90   br label %for.inc
     91 
     92 for.inc:                                          ; preds = %if.then, %for.body
     93   %inc = add i64 %i.02, 1
     94   %cmp = icmp slt i64 %inc, %n
     95   br i1 %cmp, label %for.body, label %for.end
     96 
     97 for.end:                                          ; preds = %for.inc, %entry
     98   ret void
     99 }
    100 
    101 ; SDiv is unsafe to speculate if the denominator is not known non-zero.
    102 
    103 ; CHECK-LABEL: @unsafe_sdiv_a(
    104 ; CHECK-NOT:  sdiv
    105 ; CHECK: for.body:
    106 
    107 define void @unsafe_sdiv_a(i64 %x, i64 %m, i64 %n, i32* %p, i64* %q) nounwind {
    108 entry:
    109   %or = or i64 %m, 1
    110   br label %for.body
    111 
    112 for.body:                                         ; preds = %entry, %for.inc
    113   %i.02 = phi i64 [ %inc, %for.inc ], [ 0, %entry ]
    114   %arrayidx = getelementptr inbounds i32, i32* %p, i64 %i.02
    115   %0 = load i32, i32* %arrayidx, align 4
    116   %tobool = icmp eq i32 %0, 0
    117   br i1 %tobool, label %for.inc, label %if.then
    118 
    119 if.then:                                          ; preds = %for.body
    120   %div = sdiv i64 %x, %or
    121   %arrayidx1 = getelementptr inbounds i64, i64* %q, i64 %i.02
    122   store i64 %div, i64* %arrayidx1, align 8
    123   br label %for.inc
    124 
    125 for.inc:                                          ; preds = %if.then, %for.body
    126   %inc = add i64 %i.02, 1
    127   %cmp = icmp slt i64 %inc, %n
    128   br i1 %cmp, label %for.body, label %for.end
    129 
    130 for.end:                                          ; preds = %for.inc, %entry
    131   ret void
    132 }
    133 
    134 ; SDiv is unsafe to speculate if the denominator is not known to have a zero bit.
    135 
    136 ; CHECK-LABEL: @unsafe_sdiv_b(
    137 ; CHECK-NOT:  sdiv
    138 ; CHECK: for.body:
    139 
    140 define void @unsafe_sdiv_b(i64 %x, i64 %m, i64 %n, i32* %p, i64* %q) nounwind {
    141 entry:
    142   %and = and i64 %m, -3
    143   br label %for.body
    144 
    145 for.body:                                         ; preds = %entry, %for.inc
    146   %i.02 = phi i64 [ %inc, %for.inc ], [ 0, %entry ]
    147   %arrayidx = getelementptr inbounds i32, i32* %p, i64 %i.02
    148   %0 = load i32, i32* %arrayidx, align 4
    149   %tobool = icmp eq i32 %0, 0
    150   br i1 %tobool, label %for.inc, label %if.then
    151 
    152 if.then:                                          ; preds = %for.body
    153   %div = sdiv i64 %x, %and
    154   %arrayidx1 = getelementptr inbounds i64, i64* %q, i64 %i.02
    155   store i64 %div, i64* %arrayidx1, align 8
    156   br label %for.inc
    157 
    158 for.inc:                                          ; preds = %if.then, %for.body
    159   %inc = add i64 %i.02, 1
    160   %cmp = icmp slt i64 %inc, %n
    161   br i1 %cmp, label %for.body, label %for.end
    162 
    163 for.end:                                          ; preds = %for.inc, %entry
    164   ret void
    165 }
    166 
    167 ; SDiv is unsafe to speculate inside an infinite loop.
    168 
    169 define void @unsafe_sdiv_c(i64 %a, i64 %b, i64* %p) {
    170 entry:
    171 ; CHECK: entry:
    172 ; CHECK-NOT: sdiv
    173 ; CHECK: br label %for.body
    174   br label %for.body
    175 
    176 for.body:
    177   %c = icmp eq i64 %b, 0
    178   br i1 %c, label %backedge, label %if.then
    179 
    180 if.then:
    181   %d = sdiv i64 %a, %b
    182   store i64 %d, i64* %p
    183   br label %backedge
    184 
    185 backedge:
    186   br label %for.body
    187 }
    188