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