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 9define void @safe_udiv(i64 %x, i64 %m, i64 %n, i32* %p, i64* %q) nounwind { 10entry: 11 %or = or i64 %m, 1 12 br label %for.body 13 14for.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 21if.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 27for.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 32for.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 42define void @unsafe_udiv(i64 %x, i64 %m, i64 %n, i32* %p, i64* %q) nounwind { 43entry: 44 br label %for.body 45 46for.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 53if.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 59for.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 64for.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 75define void @safe_sdiv(i64 %x, i64 %m, i64 %n, i32* %p, i64* %q) nounwind { 76entry: 77 %and = and i64 %m, -3 78 %or = or i64 %and, 1 79 br label %for.body 80 81for.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 88if.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 94for.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 99for.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 109define void @unsafe_sdiv_a(i64 %x, i64 %m, i64 %n, i32* %p, i64* %q) nounwind { 110entry: 111 %or = or i64 %m, 1 112 br label %for.body 113 114for.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 121if.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 127for.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 132for.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 142define void @unsafe_sdiv_b(i64 %x, i64 %m, i64 %n, i32* %p, i64* %q) nounwind { 143entry: 144 %and = and i64 %m, -3 145 br label %for.body 146 147for.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 154if.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 160for.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 165for.end: ; preds = %for.inc, %entry 166 ret void 167} 168 169; SDiv is unsafe to speculate inside an infinite loop. 170 171define void @unsafe_sdiv_c(i64 %a, i64 %b, i64* %p) { 172entry: 173; CHECK: entry: 174; CHECK-NOT: sdiv 175; CHECK: br label %for.body 176 br label %for.body 177 178for.body: 179 %c = icmp eq i64 %b, 0 180 br i1 %c, label %backedge, label %if.then 181 182if.then: 183 %d = sdiv i64 %a, %b 184 store i64 %d, i64* %p 185 br label %backedge 186 187backedge: 188 br label %for.body 189} 190