1; RUN: llc < %s -mcpu=generic -march=x86-64 | FileCheck %s 2 3; Optimize away zext-inreg and sext-inreg on the loop induction 4; variable using trip-count information. 5 6; CHECK-LABEL: count_up 7; CHECK-NOT: {{and|movz|sar|shl}} 8; CHECK: incq 9; CHECK-NOT: {{and|movz|sar|shl}} 10; CHECK: jne 11define void @count_up(double* %d, i64 %n) nounwind { 12entry: 13 br label %loop 14 15loop: 16 %indvar = phi i64 [ 0, %entry ], [ %indvar.next, %loop ] 17 %indvar.i8 = and i64 %indvar, 255 18 %t0 = getelementptr double, double* %d, i64 %indvar.i8 19 %t1 = load double, double* %t0 20 %t2 = fmul double %t1, 0.1 21 store double %t2, double* %t0 22 %indvar.i24 = and i64 %indvar, 16777215 23 %t3 = getelementptr double, double* %d, i64 %indvar.i24 24 %t4 = load double, double* %t3 25 %t5 = fmul double %t4, 2.3 26 store double %t5, double* %t3 27 %t6 = getelementptr double, double* %d, i64 %indvar 28 %t7 = load double, double* %t6 29 %t8 = fmul double %t7, 4.5 30 store double %t8, double* %t6 31 %indvar.next = add i64 %indvar, 1 32 %exitcond = icmp eq i64 %indvar.next, 10 33 br i1 %exitcond, label %return, label %loop 34 35return: 36 ret void 37} 38 39; CHECK-LABEL: count_down 40; CHECK-NOT: {{and|movz|sar|shl}} 41; CHECK: addq 42; CHECK-NOT: {{and|movz|sar|shl}} 43; CHECK: jne 44define void @count_down(double* %d, i64 %n) nounwind { 45entry: 46 br label %loop 47 48loop: 49 %indvar = phi i64 [ 10, %entry ], [ %indvar.next, %loop ] 50 %indvar.i8 = and i64 %indvar, 255 51 %t0 = getelementptr double, double* %d, i64 %indvar.i8 52 %t1 = load double, double* %t0 53 %t2 = fmul double %t1, 0.1 54 store double %t2, double* %t0 55 %indvar.i24 = and i64 %indvar, 16777215 56 %t3 = getelementptr double, double* %d, i64 %indvar.i24 57 %t4 = load double, double* %t3 58 %t5 = fmul double %t4, 2.3 59 store double %t5, double* %t3 60 %t6 = getelementptr double, double* %d, i64 %indvar 61 %t7 = load double, double* %t6 62 %t8 = fmul double %t7, 4.5 63 store double %t8, double* %t6 64 %indvar.next = sub i64 %indvar, 1 65 %exitcond = icmp eq i64 %indvar.next, 0 66 br i1 %exitcond, label %return, label %loop 67 68return: 69 ret void 70} 71 72; CHECK-LABEL: count_up_signed 73; CHECK-NOT: {{and|movz|sar|shl}} 74; CHECK: incq 75; CHECK-NOT: {{and|movz|sar|shl}} 76; CHECK: jne 77define void @count_up_signed(double* %d, i64 %n) nounwind { 78entry: 79 br label %loop 80 81loop: 82 %indvar = phi i64 [ 0, %entry ], [ %indvar.next, %loop ] 83 %s0 = shl i64 %indvar, 8 84 %indvar.i8 = ashr i64 %s0, 8 85 %t0 = getelementptr double, double* %d, i64 %indvar.i8 86 %t1 = load double, double* %t0 87 %t2 = fmul double %t1, 0.1 88 store double %t2, double* %t0 89 %s1 = shl i64 %indvar, 24 90 %indvar.i24 = ashr i64 %s1, 24 91 %t3 = getelementptr double, double* %d, i64 %indvar.i24 92 %t4 = load double, double* %t3 93 %t5 = fmul double %t4, 2.3 94 store double %t5, double* %t3 95 %t6 = getelementptr double, double* %d, i64 %indvar 96 %t7 = load double, double* %t6 97 %t8 = fmul double %t7, 4.5 98 store double %t8, double* %t6 99 %indvar.next = add i64 %indvar, 1 100 %exitcond = icmp eq i64 %indvar.next, 10 101 br i1 %exitcond, label %return, label %loop 102 103return: 104 ret void 105} 106 107; CHECK-LABEL: count_down_signed 108; CHECK-NOT: {{and|movz|sar|shl}} 109; CHECK: addq 110; CHECK-NOT: {{and|movz|sar|shl}} 111; CHECK: jne 112define void @count_down_signed(double* %d, i64 %n) nounwind { 113entry: 114 br label %loop 115 116loop: 117 %indvar = phi i64 [ 10, %entry ], [ %indvar.next, %loop ] 118 %s0 = shl i64 %indvar, 8 119 %indvar.i8 = ashr i64 %s0, 8 120 %t0 = getelementptr double, double* %d, i64 %indvar.i8 121 %t1 = load double, double* %t0 122 %t2 = fmul double %t1, 0.1 123 store double %t2, double* %t0 124 %s1 = shl i64 %indvar, 24 125 %indvar.i24 = ashr i64 %s1, 24 126 %t3 = getelementptr double, double* %d, i64 %indvar.i24 127 %t4 = load double, double* %t3 128 %t5 = fmul double %t4, 2.3 129 store double %t5, double* %t3 130 %t6 = getelementptr double, double* %d, i64 %indvar 131 %t7 = load double, double* %t6 132 %t8 = fmul double %t7, 4.5 133 store double %t8, double* %t6 134 %indvar.next = sub i64 %indvar, 1 135 %exitcond = icmp eq i64 %indvar.next, 0 136 br i1 %exitcond, label %return, label %loop 137 138return: 139 ret void 140} 141 142; CHECK-LABEL: another_count_up 143; CHECK-NOT: {{and|movz|sar|shl}} 144; CHECK: addq 145; CHECK-NOT: {{and|movz|sar|shl}} 146; CHECK: jne 147define void @another_count_up(double* %d, i64 %n) nounwind { 148entry: 149 br label %loop 150 151loop: 152 %indvar = phi i64 [ 18446744073709551615, %entry ], [ %indvar.next, %loop ] 153 %indvar.i8 = and i64 %indvar, 255 154 %t0 = getelementptr double, double* %d, i64 %indvar.i8 155 %t1 = load double, double* %t0 156 %t2 = fmul double %t1, 0.1 157 store double %t2, double* %t0 158 %indvar.i24 = and i64 %indvar, 16777215 159 %t3 = getelementptr double, double* %d, i64 %indvar.i24 160 %t4 = load double, double* %t3 161 %t5 = fmul double %t4, 2.3 162 store double %t5, double* %t3 163 %t6 = getelementptr double, double* %d, i64 %indvar 164 %t7 = load double, double* %t6 165 %t8 = fmul double %t7, 4.5 166 store double %t8, double* %t6 167 %indvar.next = add i64 %indvar, 1 168 %exitcond = icmp eq i64 %indvar.next, 0 169 br i1 %exitcond, label %return, label %loop 170 171return: 172 ret void 173} 174 175; CHECK-LABEL: another_count_down 176; CHECK-NOT: {{and|movz|sar|shl}} 177; CHECK: addq $-8, 178; CHECK-NOT: {{and|movz|sar|shl}} 179; CHECK: jne 180define void @another_count_down(double* %d, i64 %n) nounwind { 181entry: 182 br label %loop 183 184loop: 185 %indvar = phi i64 [ 0, %entry ], [ %indvar.next, %loop ] 186 %indvar.i8 = and i64 %indvar, 255 187 %t0 = getelementptr double, double* %d, i64 %indvar.i8 188 %t1 = load double, double* %t0 189 %t2 = fmul double %t1, 0.1 190 store double %t2, double* %t0 191 %indvar.i24 = and i64 %indvar, 16777215 192 %t3 = getelementptr double, double* %d, i64 %indvar.i24 193 %t4 = load double, double* %t3 194 %t5 = fdiv double %t4, 2.3 195 store double %t5, double* %t3 196 %t6 = getelementptr double, double* %d, i64 %indvar 197 %t7 = load double, double* %t6 198 %t8 = fmul double %t7, 4.5 199 store double %t8, double* %t6 200 %indvar.next = sub i64 %indvar, 1 201 %exitcond = icmp eq i64 %indvar.next, 18446744073709551615 202 br i1 %exitcond, label %return, label %loop 203 204return: 205 ret void 206} 207 208; CHECK-LABEL: another_count_up_signed 209; CHECK-NOT: {{and|movz|sar|shl}} 210; CHECK: addq 211; CHECK-NOT: {{and|movz|sar|shl}} 212; CHECK: jne 213define void @another_count_up_signed(double* %d, i64 %n) nounwind { 214entry: 215 br label %loop 216 217loop: 218 %indvar = phi i64 [ 18446744073709551615, %entry ], [ %indvar.next, %loop ] 219 %s0 = shl i64 %indvar, 8 220 %indvar.i8 = ashr i64 %s0, 8 221 %t0 = getelementptr double, double* %d, i64 %indvar.i8 222 %t1 = load double, double* %t0 223 %t2 = fmul double %t1, 0.1 224 store double %t2, double* %t0 225 %s1 = shl i64 %indvar, 24 226 %indvar.i24 = ashr i64 %s1, 24 227 %t3 = getelementptr double, double* %d, i64 %indvar.i24 228 %t4 = load double, double* %t3 229 %t5 = fdiv double %t4, 2.3 230 store double %t5, double* %t3 231 %t6 = getelementptr double, double* %d, i64 %indvar 232 %t7 = load double, double* %t6 233 %t8 = fmul double %t7, 4.5 234 store double %t8, double* %t6 235 %indvar.next = add i64 %indvar, 1 236 %exitcond = icmp eq i64 %indvar.next, 0 237 br i1 %exitcond, label %return, label %loop 238 239return: 240 ret void 241} 242 243; CHECK-LABEL: another_count_down_signed 244; CHECK-NOT: {{and|movz|sar|shl}} 245; CHECK: decq 246; CHECK-NOT: {{and|movz|sar|shl}} 247; CHECK: jne 248define void @another_count_down_signed(double* %d, i64 %n) nounwind { 249entry: 250 br label %loop 251 252loop: 253 %indvar = phi i64 [ 0, %entry ], [ %indvar.next, %loop ] 254 %s0 = shl i64 %indvar, 8 255 %indvar.i8 = ashr i64 %s0, 8 256 %t0 = getelementptr double, double* %d, i64 %indvar.i8 257 %t1 = load double, double* %t0 258 %t2 = fmul double %t1, 0.1 259 store double %t2, double* %t0 260 %s1 = shl i64 %indvar, 24 261 %indvar.i24 = ashr i64 %s1, 24 262 %t3 = getelementptr double, double* %d, i64 %indvar.i24 263 %t4 = load double, double* %t3 264 %t5 = fdiv double %t4, 2.3 265 store double %t5, double* %t3 266 %t6 = getelementptr double, double* %d, i64 %indvar 267 %t7 = load double, double* %t6 268 %t8 = fmul double %t7, 4.5 269 store double %t8, double* %t6 270 %indvar.next = sub i64 %indvar, 1 271 %exitcond = icmp eq i64 %indvar.next, 18446744073709551615 272 br i1 %exitcond, label %return, label %loop 273 274return: 275 ret void 276} 277