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