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