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 11 define void @count_up(double* %d, i64 %n) nounwind { 12 entry: 13 br label %loop 14 15 loop: 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 35 return: 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 44 define void @count_down(double* %d, i64 %n) nounwind { 45 entry: 46 br label %loop 47 48 loop: 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 68 return: 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 77 define void @count_up_signed(double* %d, i64 %n) nounwind { 78 entry: 79 br label %loop 80 81 loop: 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 103 return: 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 112 define void @count_down_signed(double* %d, i64 %n) nounwind { 113 entry: 114 br label %loop 115 116 loop: 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 138 return: 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 147 define void @another_count_up(double* %d, i64 %n) nounwind { 148 entry: 149 br label %loop 150 151 loop: 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 171 return: 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 180 define void @another_count_down(double* %d, i64 %n) nounwind { 181 entry: 182 br label %loop 183 184 loop: 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 204 return: 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 213 define void @another_count_up_signed(double* %d, i64 %n) nounwind { 214 entry: 215 br label %loop 216 217 loop: 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 239 return: 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 248 define void @another_count_down_signed(double* %d, i64 %n) nounwind { 249 entry: 250 br label %loop 251 252 loop: 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 274 return: 275 ret void 276 } 277