OLD | NEW |
(Empty) | |
| 1 ; RUN: opt < %s -nacl-promote-ints -S | FileCheck %s |
| 2 |
| 3 declare void @consume_i16(i16 %a) |
| 4 |
| 5 ; CHECK: @sext_to_illegal |
| 6 ; CHECK-NEXT: %a40 = sext i32 %a to i64 |
| 7 ; (0xFFFFFFFFFF) |
| 8 define void @sext_to_illegal(i32 %a) { |
| 9 %a40 = sext i32 %a to i40 |
| 10 ret void |
| 11 } |
| 12 |
| 13 ; CHECK; @sext_from_illegal |
| 14 define void @sext_from_illegal(i8 %a) { |
| 15 ; CHECK: call void @consume_i16(i16 -2) |
| 16 %c12 = sext i12 -2 to i16 |
| 17 call void @consume_i16(i16 %c12) |
| 18 ; CHECK: %a12 = sext i8 %a to i16 |
| 19 %a12 = sext i8 %a to i12 |
| 20 ; CHECK: %a12.getsign = shl i16 %a12, 4 |
| 21 ; CHECK-NEXT: %a16 = ashr i16 %a12.getsign, 4 |
| 22 %a16 = sext i12 %a12 to i16 |
| 23 ; CHECK: %a12.getsign1 = shl i16 %a12, 4 |
| 24 ; CHECK-NEXT: %a14 = ashr i16 %a12.getsign1, 4 |
| 25 ; (0x3FFF) |
| 26 %a14 = sext i12 %a12 to i14 |
| 27 ; CHECK-NEXT: %a12.getsign2 = shl i16 %a12, 4 |
| 28 ; CHECK-NEXT: %a12.signed = ashr i16 %a12.getsign2, 4 |
| 29 ; CHECK-NEXT: %a24 = sext i16 %a12.signed to i32 |
| 30 ; (0xFFFFFF) |
| 31 %a24 = sext i12 %a12 to i24 |
| 32 |
| 33 %a37 = zext i8 %a to i37 |
| 34 ; CHECK: %a37.getsign = shl i64 %a37, 27 |
| 35 ; CHECK-NEXT: %a64 = ashr i64 %a37.getsign, 27 |
| 36 %a64 = sext i37 %a37 to i64 |
| 37 ret void |
| 38 } |
| 39 |
| 40 ; CHECK: @zext_to_illegal |
| 41 define void @zext_to_illegal(i32 %a) { |
| 42 ; CHECK: zext i32 %a to i64 |
| 43 ; CHECK-NOT: and |
| 44 %a40 = zext i32 %a to i40 |
| 45 ret void |
| 46 } |
| 47 |
| 48 ; CHECK: @zext_from_illegal |
| 49 define void @zext_from_illegal(i8 %a) { |
| 50 ; get some illegal values to start with |
| 51 %a24 = zext i8 %a to i24 |
| 52 %a40 = zext i8 %a to i40 |
| 53 %a18 = zext i8 %a to i18 |
| 54 |
| 55 ; CHECK: %a32 = and i32 %a24, 16777215 |
| 56 ; (0xFFFFFF) |
| 57 %a32 = zext i24 %a24 to i32 |
| 58 |
| 59 ; CHECK: %b24 = and i32 %a18, 262143 |
| 60 ; (0x3FFFF) |
| 61 %b24 = zext i18 %a18 to i24 |
| 62 |
| 63 ; CHECK: %a24.clear = and i32 %a24, 16777215 |
| 64 ; CHECK: %b40 = zext i32 %a24.clear to i64 |
| 65 %b40 = zext i24 %a24 to i40 |
| 66 |
| 67 ; CHECK: call void @consume_i16(i16 4094) |
| 68 %c16 = zext i12 -2 to i16 |
| 69 call void @consume_i16(i16 %c16) |
| 70 ; CHECK: call void @consume_i16(i16 4094) |
| 71 %c14 = zext i12 -2 to i14 |
| 72 %c16.2 = zext i14 %c14 to i16 |
| 73 call void @consume_i16(i16 %c16.2) |
| 74 ret void |
| 75 } |
| 76 |
| 77 ; CHECK: @trunc_from_illegal |
| 78 define void @trunc_from_illegal(i8 %a) { |
| 79 %a24 = zext i8 %a to i24 |
| 80 ; CHECK: %a16 = trunc i32 %a24 to i16 |
| 81 %a16 = trunc i24 %a24 to i16 |
| 82 ret void |
| 83 } |
| 84 |
| 85 ; CHECK: @trunc_to_illegal |
| 86 define void @trunc_to_illegal(i8 %a8) { |
| 87 %a = zext i8 %a8 to i32 |
| 88 ; CHECK-NOT: trunc i32 %a |
| 89 ; CHECK-NOT: and |
| 90 %a24 = trunc i32 %a to i24 |
| 91 |
| 92 ; CHECK: %a12 = trunc i32 %a24 to i16 |
| 93 ; CHECK-NOT: and |
| 94 %a12 = trunc i24 %a24 to i12 |
| 95 ret void |
| 96 } |
| 97 |
| 98 ; CHECK: @icmpsigned |
| 99 define void @icmpsigned(i32 %a) { |
| 100 %shl = trunc i32 %a to i24 |
| 101 ; CHECK: %shl.getsign = shl i32 %shl, 8 |
| 102 ; CHECK-NEXT: %shl.signed = ashr i32 %shl.getsign, 8 |
| 103 ; CHECK-NEXT: %cmp = icmp slt i32 %shl.signed, -2 |
| 104 %cmp = icmp slt i24 %shl, -2 |
| 105 ret void |
| 106 } |
| 107 |
| 108 ; Bitcasts are left unchanged. |
| 109 %struct.ints = type { i32, i32 } |
| 110 ; CHECK: @bc1 |
| 111 ; CHECK-NEXT: %bc1 = bitcast i32* %a to i40* |
| 112 ; CHECK-NEXT: %bc2 = bitcast i40* %bc1 to i32* |
| 113 ; CHECK-NEXT: %bc3 = bitcast %struct.ints* null to i40* |
| 114 ; CHECK-NEXT: %bc4 = bitcast i40* %bc1 to %struct.ints* |
| 115 define i32* @bc1(i32* %a) { |
| 116 %bc1 = bitcast i32* %a to i40* |
| 117 %bc2 = bitcast i40* %bc1 to i32* |
| 118 %bc3 = bitcast %struct.ints* null to i40* |
| 119 %bc4 = bitcast i40* %bc1 to %struct.ints* |
| 120 ret i32* %bc2 |
| 121 } |
| 122 |
| 123 ; CHECK: zext i32 %a to i64 |
| 124 ; CHECK: and i64 %a40, 255 |
| 125 define void @and1(i32 %a) { |
| 126 %a40 = zext i32 %a to i40 |
| 127 %and = and i40 %a40, 255 |
| 128 ret void |
| 129 } |
| 130 |
| 131 ; CHECK: @andi3 |
| 132 define void @andi3(i8 %a) { |
| 133 %a3 = trunc i8 %a to i3 |
| 134 ; CHECK: and i8 %a3, 2 |
| 135 %and = and i3 %a3, 2 |
| 136 ret void |
| 137 } |
| 138 |
| 139 ; CHECK: @ori7 |
| 140 define void @ori7(i8 %a, i8 %b) { |
| 141 %a7 = trunc i8 %a to i7 |
| 142 %b7 = trunc i8 %b to i7 |
| 143 ; CHECK: %or = or i8 %a7, %b7 |
| 144 %or = or i7 %a7, %b7 |
| 145 ret void |
| 146 } |
| 147 |
| 148 ; CHECK: @add1 |
| 149 define void @add1(i16 %a) { |
| 150 ; CHECK-NEXT: %a24 = sext i16 %a to i32 |
| 151 %a24 = sext i16 %a to i24 |
| 152 ; CHECK-NEXT: %sum = add i32 %a24, 16777214 |
| 153 %sum = add i24 %a24, -2 |
| 154 ; CHECK-NEXT: %sumnsw = add nsw i32 %a24, 16777214 |
| 155 %sumnsw = add nsw i24 %a24, -2 |
| 156 ; CHECK-NEXT: %sumnuw = add nuw i32 %a24, 16777214 |
| 157 %sumnuw = add nuw i24 %a24, -2 |
| 158 ; CHECK-NEXT: %sumnw = add nuw nsw i32 %a24, 16777214 |
| 159 %sumnw = add nuw nsw i24 %a24, -2 |
| 160 ret void |
| 161 } |
| 162 |
| 163 ; CHECK: @mul1 |
| 164 define void @mul1(i32 %a, i32 %b) { |
| 165 ; CHECK-NEXT: %a33 = sext i32 %a to i64 |
| 166 %a33 = sext i32 %a to i33 |
| 167 ; CHECK-NEXT: %b33 = sext i32 %b to i64 |
| 168 %b33 = sext i32 %b to i33 |
| 169 ; CHECK-NEXT: %product = mul i64 %a33, %b33 |
| 170 %product = mul i33 %a33, %b33 |
| 171 ; CHECK-NEXT: %prodnw = mul nuw nsw i64 %a33, %b33 |
| 172 %prodnw = mul nuw nsw i33 %a33, %b33 |
| 173 ret void |
| 174 } |
| 175 |
| 176 ; CHECK: @shl1 |
| 177 define void @shl1(i16 %a) { |
| 178 %a24 = zext i16 %a to i24 |
| 179 ; CHECK: %ashl = shl i32 %a24, 5 |
| 180 %ashl = shl i24 %a24, 5 |
| 181 |
| 182 ; CHECK-NEXT: %ashl2 = shl i32 %a24, 1 |
| 183 %ashl2 = shl i24 %a24, 4278190081 ;0xFF000001 |
| 184 |
| 185 %b24 = zext i16 %a to i24 |
| 186 ; CHECK: %b24.clear = and i32 %b24, 16777215 |
| 187 ; CHECK-NEXT: %bshl = shl i32 %a24, %b24.clear |
| 188 %bshl = shl i24 %a24, %b24 |
| 189 ret void |
| 190 } |
| 191 |
| 192 ; CHECK: @shlnuw |
| 193 define void @shlnuw(i16 %a) { |
| 194 %a12 = trunc i16 %a to i12 |
| 195 ; CHECK: %ashl = shl nuw i16 %a12, 5 |
| 196 %ashl = shl nuw i12 %a12, 5 |
| 197 ret void |
| 198 } |
| 199 |
| 200 ; CHECK: @lshr1 |
| 201 define void @lshr1(i16 %a) { |
| 202 %a24 = zext i16 %a to i24 |
| 203 ; CHECK: %a24.clear = and i32 %a24, 16777215 |
| 204 ; CHECK-NEXT: %b = lshr i32 %a24.clear, 20 |
| 205 %b = lshr i24 %a24, 20 |
| 206 ; CHECK-NEXT: %a24.clear1 = and i32 %a24, 16777215 |
| 207 ; CHECK-NEXT: %c = lshr i32 %a24.clear1, 5 |
| 208 %c = lshr i24 %a24, 5 |
| 209 |
| 210 %b24 = zext i16 %a to i24 |
| 211 %d = lshr i24 %a24, %b24 |
| 212 ; CHECK: %a24.clear2 = and i32 %a24, 16777215 |
| 213 ; CHECK-NEXT: %b24.clear = and i32 %b24, 16777215 |
| 214 ; CHECK-NEXT: %d = lshr i32 %a24.clear2, %b24.clear |
| 215 ret void |
| 216 } |
| 217 |
| 218 ; CHECK: @ashr1 |
| 219 define void @ashr1(i16 %a) { |
| 220 %a24 = sext i16 %a to i24 |
| 221 ; CHECK: %a24.getsign = shl i32 %a24, 8 |
| 222 ; CHECK-NEXT: %b24 = ashr i32 %a24.getsign, 19 |
| 223 %b24 = ashr i24 %a24, 11 |
| 224 ; CHECK-NEXT: %a24.getsign1 = shl i32 %a24, 8 |
| 225 ; CHECK-NEXT: %b24.clear = and i32 %b24, 16777215 |
| 226 ; CHECK-NEXT: %a24.shamt = add i32 %b24.clear, 8 |
| 227 ; CHECK-NEXT: %c = ashr i32 %a24.getsign1, %a24.shamt |
| 228 %c = ashr i24 %a24, %b24 |
| 229 ret void |
| 230 } |
| 231 |
| 232 ; CHECK: @phi_icmp |
| 233 define void @phi_icmp(i32 %a) { |
| 234 entry: |
| 235 br label %loop |
| 236 loop: |
| 237 ; CHECK: %phi40 = phi i64 [ 1099511627774, %entry ], [ %phi40, %loop ] |
| 238 %phi40 = phi i40 [ -2, %entry ], [ %phi40, %loop ] |
| 239 ; CHECK-NEXT: %phi40.clear = and i64 %phi40, 1099511627775 |
| 240 ; CHECK-NEXT: %b = icmp eq i64 %phi40.clear, 1099511627775 |
| 241 %b = icmp eq i40 %phi40, -1 |
| 242 ; CHECK-NEXT: br i1 %b, label %loop, label %end |
| 243 br i1 %b, label %loop, label %end |
| 244 end: |
| 245 ret void |
| 246 } |
| 247 |
| 248 ; CHECK: @icmp_ult |
| 249 define void @icmp_ult(i32 %a) { |
| 250 %a40 = zext i32 %a to i40 |
| 251 ; CHECK: %a40.clear = and i64 %a40, 1099511627775 |
| 252 ; CHECK-NEXT: %b = icmp ult i64 %a40.clear, 1099511627774 |
| 253 %b = icmp ult i40 %a40, -2 |
| 254 |
| 255 ; CHECK: %a40.clear1 = and i64 %a40, 1099511627775 |
| 256 ; CHECK-NEXT: %b40.clear = and i64 %b40, 1099511627775 |
| 257 ; CHECK-NEXT: %c = icmp ult i64 %a40.clear1, %b40.clear |
| 258 %b40 = zext i32 %a to i40 |
| 259 %c = icmp ult i40 %a40, %b40 |
| 260 ret void |
| 261 } |
| 262 |
| 263 ; CHECK: @select1 |
| 264 define void @select1(i32 %a) { |
| 265 %a40 = zext i32 %a to i40 |
| 266 ; CHECK: %s40 = select i1 true, i64 %a40, i64 1099511627775 |
| 267 %s40 = select i1 true, i40 %a40, i40 -1 |
| 268 ret void |
| 269 } |
| 270 |
| 271 ; Allocas are left unchanged. |
| 272 ; CHECK: @alloca40 |
| 273 ; CHECK: %a = alloca i40, align 8 |
| 274 define void @alloca40() { |
| 275 %a = alloca i40, align 8 |
| 276 %b = bitcast i40* %a to i8* |
| 277 %c = load i8* %b |
| 278 ret void |
| 279 } |
| 280 |
| 281 ; CHECK: @load24 |
| 282 ; CHECK: %bc.loty = bitcast i24* %bc to i16* |
| 283 ; CHECK-NEXT: %load.lo = load i16* %bc.loty |
| 284 ; CHECK-NEXT: %load.lo.ext = zext i16 %load.lo to i32 |
| 285 ; CHECK-NEXT: %bc.hi = getelementptr i16* %bc.loty, i32 1 |
| 286 ; CHECK-NEXT: %bc.hity = bitcast i16* %bc.hi to i8* |
| 287 ; CHECK-NEXT: %load.hi = load i8* %bc.hity |
| 288 ; CHECK-NEXT: %load.hi.ext = zext i8 %load.hi to i32 |
| 289 ; CHECK-NEXT: %load.hi.ext.sh = shl i32 %load.hi.ext, 16 |
| 290 ; CHECK-NEXT: %load = or i32 %load.lo.ext, %load.hi.ext.sh |
| 291 define void @load24(i8* %a) { |
| 292 %bc = bitcast i8* %a to i24* |
| 293 %load = load i24* %bc, align 8 |
| 294 ret void |
| 295 } |
| 296 |
| 297 ; CHECK: @load48 |
| 298 ; CHECK: %bc.loty = bitcast i48* %bc to i32* |
| 299 ; CHECK-NEXT: %load.lo = load i32* %bc.loty |
| 300 ; CHECK-NEXT: %load.lo.ext = zext i32 %load.lo to i64 |
| 301 ; CHECK-NEXT: %bc.hi = getelementptr i32* %bc.loty, i32 1 |
| 302 ; CHECK-NEXT: %bc.hity = bitcast i32* %bc.hi to i16* |
| 303 ; CHECK-NEXT: %load.hi = load i16* %bc.hity |
| 304 ; CHECK-NEXT: %load.hi.ext = zext i16 %load.hi to i64 |
| 305 ; CHECK-NEXT: %load.hi.ext.sh = shl i64 %load.hi.ext, 32 |
| 306 ; CHECK-NEXT: %load = or i64 %load.lo.ext, %load.hi.ext.sh |
| 307 define void @load48(i32* %a) { |
| 308 %bc = bitcast i32* %a to i48* |
| 309 %load = load i48* %bc, align 8 |
| 310 ret void |
| 311 } |
| 312 |
| 313 ; CHECK: @load56 |
| 314 ; CHECK: %bc = bitcast i32* %a to i56* |
| 315 ; CHECK-NEXT: %bc.loty = bitcast i56* %bc to i32* |
| 316 ; CHECK-NEXT: %load.lo = load i32* %bc.loty |
| 317 ; CHECK-NEXT: %load.lo.ext = zext i32 %load.lo to i64 |
| 318 ; CHECK-NEXT: %bc.hi = getelementptr i32* %bc.loty, i32 1 |
| 319 ; CHECK-NEXT: %bc.hity = bitcast i32* %bc.hi to i24* |
| 320 ; CHECK-NEXT: %bc.hity.loty = bitcast i24* %bc.hity to i16* |
| 321 ; CHECK-NEXT: %load.hi.lo = load i16* %bc.hity.loty |
| 322 ; CHECK-NEXT: %load.hi.lo.ext = zext i16 %load.hi.lo to i32 |
| 323 ; CHECK-NEXT: %bc.hity.hi = getelementptr i16* %bc.hity.loty, i32 1 |
| 324 ; CHECK-NEXT: %bc.hity.hity = bitcast i16* %bc.hity.hi to i8* |
| 325 ; CHECK-NEXT: %load.hi.hi = load i8* %bc.hity.hity |
| 326 ; CHECK-NEXT: %load.hi.hi.ext = zext i8 %load.hi.hi to i32 |
| 327 ; CHECK-NEXT: %load.hi.hi.ext.sh = shl i32 %load.hi.hi.ext, 16 |
| 328 ; CHECK-NEXT: %load.hi = or i32 %load.hi.lo.ext, %load.hi.hi.ext.sh |
| 329 ; CHECK-NEXT: %load.hi.ext = zext i32 %load.hi to i64 |
| 330 ; CHECK-NEXT: %load.hi.ext.sh = shl i64 %load.hi.ext, 32 |
| 331 ; CHECK-NEXT: %load = or i64 %load.lo.ext, %load.hi.ext.sh |
| 332 define void @load56(i32* %a) { |
| 333 %bc = bitcast i32* %a to i56* |
| 334 %load = load i56* %bc |
| 335 ret void |
| 336 } |
| 337 |
| 338 ; CHECK: @store24 |
| 339 ; CHECK: %b24 = zext i8 %b to i32 |
| 340 ; CHECK-NEXT: %bc.loty = bitcast i24* %bc to i16* |
| 341 ; CHECK-NEXT: %b24.lo = trunc i32 %b24 to i16 |
| 342 ; CHECK-NEXT: store i16 %b24.lo, i16* %bc.loty |
| 343 ; CHECK-NEXT: %b24.hi.sh = lshr i32 %b24, 16 |
| 344 ; CHECK-NEXT: %bc.hi = getelementptr i16* %bc.loty, i32 1 |
| 345 ; CHECK-NEXT: %b24.hi = trunc i32 %b24.hi.sh to i8 |
| 346 ; CHECK-NEXT: %bc.hity = bitcast i16* %bc.hi to i8* |
| 347 ; CHECK-NEXT: store i8 %b24.hi, i8* %bc.hity |
| 348 define void @store24(i8* %a, i8 %b) { |
| 349 %bc = bitcast i8* %a to i24* |
| 350 %b24 = zext i8 %b to i24 |
| 351 store i24 %b24, i24* %bc |
| 352 ret void |
| 353 } |
| 354 |
| 355 ; CHECK: @store56 |
| 356 ; CHECK: %b56 = zext i8 %b to i64 |
| 357 ; CHECK-NEXT: %bc.loty = bitcast i56* %bc to i32* |
| 358 ; CHECK-NEXT: %b56.lo = trunc i64 %b56 to i32 |
| 359 ; CHECK-NEXT: store i32 %b56.lo, i32* %bc.loty |
| 360 ; CHECK-NEXT: %b56.hi.sh = lshr i64 %b56, 32 |
| 361 ; CHECK-NEXT: %bc.hi = getelementptr i32* %bc.loty, i32 1 |
| 362 ; CHECK-NEXT: %bc.hity = bitcast i32* %bc.hi to i24* |
| 363 ; CHECK-NEXT: %bc.hity.loty = bitcast i24* %bc.hity to i16* |
| 364 ; CHECK-NEXT: %b56.hi.sh.lo = trunc i64 %b56.hi.sh to i16 |
| 365 ; CHECK-NEXT: store i16 %b56.hi.sh.lo, i16* %bc.hity.loty |
| 366 ; CHECK-NEXT: %b56.hi.sh.hi.sh = lshr i64 %b56.hi.sh, 16 |
| 367 ; CHECK-NEXT: %bc.hity.hi = getelementptr i16* %bc.hity.loty, i32 1 |
| 368 ; CHECK-NEXT: %b56.hi.sh.hi = trunc i64 %b56.hi.sh.hi.sh to i8 |
| 369 ; CHECK-NEXT: %bc.hity.hity = bitcast i16* %bc.hity.hi to i8* |
| 370 ; CHECK-NEXT: store i8 %b56.hi.sh.hi, i8* %bc.hity.hity |
| 371 define void @store56(i8* %a, i8 %b) { |
| 372 %bc = bitcast i8* %a to i56* |
| 373 %b56 = zext i8 %b to i56 |
| 374 store i56 %b56, i56* %bc |
| 375 ret void |
| 376 } |
| 377 |
| 378 ; CHECK: @undefoperand |
| 379 ; CHECK-NEXT: %a40 = zext i32 %a to i64 |
| 380 ; CHECK-NEXT: %au = and i64 %a40, undef |
| 381 define void @undefoperand(i32 %a) { |
| 382 %a40 = zext i32 %a to i40 |
| 383 %au = and i40 %a40, undef |
| 384 ret void |
| 385 } |
| 386 |
| 387 ; CHECK: @switch |
| 388 ; CHECK-NEXT: %a24 = zext i16 %a to i32 |
| 389 ; CHECK-NEXT: %a24.clear = and i32 %a24, 16777215 |
| 390 ; CHECK-NEXT: switch i32 %a24.clear, label %end [ |
| 391 ; CHECK-NEXT: i32 0, label %if1 |
| 392 ; CHECK-NEXT: i32 1, label %if2 |
| 393 define void @switch(i16 %a) { |
| 394 %a24 = zext i16 %a to i24 |
| 395 switch i24 %a24, label %end [ |
| 396 i24 0, label %if1 |
| 397 i24 1, label %if2 |
| 398 ] |
| 399 if1: |
| 400 ret void |
| 401 if2: |
| 402 ret void |
| 403 end: |
| 404 ret void |
| 405 } |
| 406 |
| 407 |
| 408 ; The getelementptr here should be handled unchanged. |
| 409 ; CHECK: @pointer_to_array |
| 410 ; CHECK: %element_ptr = getelementptr [2 x i40]* %ptr, i32 0, i32 0 |
| 411 define void @pointer_to_array([2 x i40]* %ptr) { |
| 412 %element_ptr = getelementptr [2 x i40]* %ptr, i32 0, i32 0 |
| 413 load i40* %element_ptr |
| 414 ret void |
| 415 } |
OLD | NEW |