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 9define void @safe_udiv(i64 %x, i64 %m, i64 %n, i32* %p, i64* %q) nounwind { 10entry: 11 br label %for.body 12 13for.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 20if.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 26for.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 31for.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 41define void @unsafe_udiv(i64 %x, i64 %m, i64 %n, i32* %p, i64* %q) nounwind { 42entry: 43 br label %for.body 44 45for.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 52if.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 58for.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 63for.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 74define void @safe_sdiv(i64 %x, i64 %m, i64 %n, i32* %p, i64* %q) nounwind { 75entry: 76 %and = and i64 %m, -3 77 br label %for.body 78 79for.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 86if.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 92for.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 97for.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 107define void @unsafe_sdiv_a(i64 %x, i64 %m, i64 %n, i32* %p, i64* %q) nounwind { 108entry: 109 %or = or i64 %m, 1 110 br label %for.body 111 112for.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 119if.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 125for.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 130for.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 140define void @unsafe_sdiv_b(i64 %x, i64 %m, i64 %n, i32* %p, i64* %q) nounwind { 141entry: 142 %and = and i64 %m, -3 143 br label %for.body 144 145for.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 152if.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 158for.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 163for.end: ; preds = %for.inc, %entry 164 ret void 165} 166 167; SDiv is unsafe to speculate inside an infinite loop. 168 169define void @unsafe_sdiv_c(i64 %a, i64 %b, i64* %p) { 170entry: 171; CHECK: entry: 172; CHECK-NOT: sdiv 173; CHECK: br label %for.body 174 br label %for.body 175 176for.body: 177 %c = icmp eq i64 %b, 0 178 br i1 %c, label %backedge, label %if.then 179 180if.then: 181 %d = sdiv i64 %a, %b 182 store i64 %d, i64* %p 183 br label %backedge 184 185backedge: 186 br label %for.body 187} 188