1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=i686-unknown < %s | FileCheck %s --check-prefix=X32 3; RUN: llc -mtriple=x86_64-unknown < %s | FileCheck %s --check-prefix=X64 4 5@array = weak dso_local global [4 x i32] zeroinitializer 6 7define dso_local i32 @test_lshr_and(i32 %x) { 8; X32-LABEL: test_lshr_and: 9; X32: # %bb.0: 10; X32-NEXT: movl {{[0-9]+}}(%esp), %eax 11; X32-NEXT: andl $12, %eax 12; X32-NEXT: movl array(%eax), %eax 13; X32-NEXT: retl 14; 15; X64-LABEL: test_lshr_and: 16; X64: # %bb.0: 17; X64-NEXT: # kill: def $edi killed $edi def $rdi 18; X64-NEXT: shrl $2, %edi 19; X64-NEXT: andl $3, %edi 20; X64-NEXT: movl array(,%rdi,4), %eax 21; X64-NEXT: retq 22 %tmp2 = lshr i32 %x, 2 23 %tmp3 = and i32 %tmp2, 3 24 %tmp4 = getelementptr [4 x i32], ptr @array, i32 0, i32 %tmp3 25 %tmp5 = load i32, ptr %tmp4, align 4 26 ret i32 %tmp5 27} 28 29define dso_local ptr @test_exact1(i32 %a, i32 %b, ptr %x) { 30; X32-LABEL: test_exact1: 31; X32: # %bb.0: 32; X32-NEXT: movl {{[0-9]+}}(%esp), %eax 33; X32-NEXT: subl {{[0-9]+}}(%esp), %eax 34; X32-NEXT: sarl %eax 35; X32-NEXT: addl {{[0-9]+}}(%esp), %eax 36; X32-NEXT: retl 37; 38; X64-LABEL: test_exact1: 39; X64: # %bb.0: 40; X64-NEXT: subl %edi, %esi 41; X64-NEXT: sarl $3, %esi 42; X64-NEXT: movslq %esi, %rax 43; X64-NEXT: leaq (%rdx,%rax,4), %rax 44; X64-NEXT: retq 45 %sub = sub i32 %b, %a 46 %shr = ashr exact i32 %sub, 3 47 %gep = getelementptr inbounds i32, ptr %x, i32 %shr 48 ret ptr %gep 49} 50 51define dso_local ptr @test_exact2(i32 %a, i32 %b, ptr %x) { 52; X32-LABEL: test_exact2: 53; X32: # %bb.0: 54; X32-NEXT: movl {{[0-9]+}}(%esp), %eax 55; X32-NEXT: subl {{[0-9]+}}(%esp), %eax 56; X32-NEXT: sarl %eax 57; X32-NEXT: addl {{[0-9]+}}(%esp), %eax 58; X32-NEXT: retl 59; 60; X64-LABEL: test_exact2: 61; X64: # %bb.0: 62; X64-NEXT: subl %edi, %esi 63; X64-NEXT: sarl $3, %esi 64; X64-NEXT: movslq %esi, %rax 65; X64-NEXT: leaq (%rdx,%rax,4), %rax 66; X64-NEXT: retq 67 %sub = sub i32 %b, %a 68 %shr = ashr exact i32 %sub, 3 69 %gep = getelementptr inbounds i32, ptr %x, i32 %shr 70 ret ptr %gep 71} 72 73define dso_local ptr @test_exact3(i32 %a, i32 %b, ptr %x) { 74; X32-LABEL: test_exact3: 75; X32: # %bb.0: 76; X32-NEXT: movl {{[0-9]+}}(%esp), %eax 77; X32-NEXT: subl {{[0-9]+}}(%esp), %eax 78; X32-NEXT: addl {{[0-9]+}}(%esp), %eax 79; X32-NEXT: retl 80; 81; X64-LABEL: test_exact3: 82; X64: # %bb.0: 83; X64-NEXT: subl %edi, %esi 84; X64-NEXT: sarl $2, %esi 85; X64-NEXT: movslq %esi, %rax 86; X64-NEXT: leaq (%rdx,%rax,4), %rax 87; X64-NEXT: retq 88 %sub = sub i32 %b, %a 89 %shr = ashr exact i32 %sub, 2 90 %gep = getelementptr inbounds i32, ptr %x, i32 %shr 91 ret ptr %gep 92} 93 94define dso_local ptr @test_exact4(i32 %a, i32 %b, ptr %x) { 95; X32-LABEL: test_exact4: 96; X32: # %bb.0: 97; X32-NEXT: movl {{[0-9]+}}(%esp), %eax 98; X32-NEXT: subl {{[0-9]+}}(%esp), %eax 99; X32-NEXT: shrl %eax 100; X32-NEXT: addl {{[0-9]+}}(%esp), %eax 101; X32-NEXT: retl 102; 103; X64-LABEL: test_exact4: 104; X64: # %bb.0: 105; X64-NEXT: # kill: def $esi killed $esi def $rsi 106; X64-NEXT: subl %edi, %esi 107; X64-NEXT: shrl $3, %esi 108; X64-NEXT: leaq (%rdx,%rsi,4), %rax 109; X64-NEXT: retq 110 %sub = sub i32 %b, %a 111 %shr = lshr exact i32 %sub, 3 112 %gep = getelementptr inbounds i32, ptr %x, i32 %shr 113 ret ptr %gep 114} 115 116define dso_local ptr @test_exact5(i32 %a, i32 %b, ptr %x) { 117; X32-LABEL: test_exact5: 118; X32: # %bb.0: 119; X32-NEXT: movl {{[0-9]+}}(%esp), %eax 120; X32-NEXT: subl {{[0-9]+}}(%esp), %eax 121; X32-NEXT: shrl %eax 122; X32-NEXT: addl {{[0-9]+}}(%esp), %eax 123; X32-NEXT: retl 124; 125; X64-LABEL: test_exact5: 126; X64: # %bb.0: 127; X64-NEXT: # kill: def $esi killed $esi def $rsi 128; X64-NEXT: subl %edi, %esi 129; X64-NEXT: shrl $3, %esi 130; X64-NEXT: leaq (%rdx,%rsi,4), %rax 131; X64-NEXT: retq 132 %sub = sub i32 %b, %a 133 %shr = lshr exact i32 %sub, 3 134 %gep = getelementptr inbounds i32, ptr %x, i32 %shr 135 ret ptr %gep 136} 137 138define dso_local ptr @test_exact6(i32 %a, i32 %b, ptr %x) { 139; X32-LABEL: test_exact6: 140; X32: # %bb.0: 141; X32-NEXT: movl {{[0-9]+}}(%esp), %eax 142; X32-NEXT: subl {{[0-9]+}}(%esp), %eax 143; X32-NEXT: addl {{[0-9]+}}(%esp), %eax 144; X32-NEXT: retl 145; 146; X64-LABEL: test_exact6: 147; X64: # %bb.0: 148; X64-NEXT: # kill: def $esi killed $esi def $rsi 149; X64-NEXT: subl %edi, %esi 150; X64-NEXT: leaq (%rsi,%rdx), %rax 151; X64-NEXT: retq 152 %sub = sub i32 %b, %a 153 %shr = lshr exact i32 %sub, 2 154 %gep = getelementptr inbounds i32, ptr %x, i32 %shr 155 ret ptr %gep 156} 157 158; PR42644 - https://bugs.llvm.org/show_bug.cgi?id=42644 159 160define i64 @ashr_add_shl_i32(i64 %r) nounwind { 161; X32-LABEL: ashr_add_shl_i32: 162; X32: # %bb.0: 163; X32-NEXT: movl {{[0-9]+}}(%esp), %eax 164; X32-NEXT: incl %eax 165; X32-NEXT: movl %eax, %edx 166; X32-NEXT: sarl $31, %edx 167; X32-NEXT: retl 168; 169; X64-LABEL: ashr_add_shl_i32: 170; X64: # %bb.0: 171; X64-NEXT: incl %edi 172; X64-NEXT: movslq %edi, %rax 173; X64-NEXT: retq 174 %conv = shl i64 %r, 32 175 %sext = add i64 %conv, 4294967296 176 %conv1 = ashr i64 %sext, 32 177 ret i64 %conv1 178} 179 180define i64 @ashr_add_shl_i8(i64 %r) nounwind { 181; X32-LABEL: ashr_add_shl_i8: 182; X32: # %bb.0: 183; X32-NEXT: movb {{[0-9]+}}(%esp), %al 184; X32-NEXT: addb $2, %al 185; X32-NEXT: movsbl %al, %eax 186; X32-NEXT: movl %eax, %edx 187; X32-NEXT: sarl $31, %edx 188; X32-NEXT: retl 189; 190; X64-LABEL: ashr_add_shl_i8: 191; X64: # %bb.0: 192; X64-NEXT: addb $2, %dil 193; X64-NEXT: movsbq %dil, %rax 194; X64-NEXT: retq 195 %conv = shl i64 %r, 56 196 %sext = add i64 %conv, 144115188075855872 197 %conv1 = ashr i64 %sext, 56 198 ret i64 %conv1 199} 200 201define <4 x i32> @ashr_add_shl_v4i8(<4 x i32> %r) nounwind { 202; X32-LABEL: ashr_add_shl_v4i8: 203; X32: # %bb.0: 204; X32-NEXT: pushl %edi 205; X32-NEXT: pushl %esi 206; X32-NEXT: movl {{[0-9]+}}(%esp), %eax 207; X32-NEXT: movb {{[0-9]+}}(%esp), %cl 208; X32-NEXT: movb {{[0-9]+}}(%esp), %dl 209; X32-NEXT: movb {{[0-9]+}}(%esp), %ch 210; X32-NEXT: movb {{[0-9]+}}(%esp), %dh 211; X32-NEXT: incb %dh 212; X32-NEXT: movsbl %dh, %esi 213; X32-NEXT: incb %ch 214; X32-NEXT: movsbl %ch, %edi 215; X32-NEXT: incb %dl 216; X32-NEXT: movsbl %dl, %edx 217; X32-NEXT: incb %cl 218; X32-NEXT: movsbl %cl, %ecx 219; X32-NEXT: movl %ecx, 12(%eax) 220; X32-NEXT: movl %edx, 8(%eax) 221; X32-NEXT: movl %edi, 4(%eax) 222; X32-NEXT: movl %esi, (%eax) 223; X32-NEXT: popl %esi 224; X32-NEXT: popl %edi 225; X32-NEXT: retl $4 226; 227; X64-LABEL: ashr_add_shl_v4i8: 228; X64: # %bb.0: 229; X64-NEXT: pslld $24, %xmm0 230; X64-NEXT: paddd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0 231; X64-NEXT: psrad $24, %xmm0 232; X64-NEXT: retq 233 %conv = shl <4 x i32> %r, <i32 24, i32 24, i32 24, i32 24> 234 %sext = add <4 x i32> %conv, <i32 16777216, i32 16777216, i32 16777216, i32 16777216> 235 %conv1 = ashr <4 x i32> %sext, <i32 24, i32 24, i32 24, i32 24> 236 ret <4 x i32> %conv1 237} 238 239define i64 @ashr_add_shl_i36(i64 %r) nounwind { 240; X32-LABEL: ashr_add_shl_i36: 241; X32: # %bb.0: 242; X32-NEXT: movl {{[0-9]+}}(%esp), %edx 243; X32-NEXT: shll $4, %edx 244; X32-NEXT: movl %edx, %eax 245; X32-NEXT: sarl $4, %eax 246; X32-NEXT: sarl $31, %edx 247; X32-NEXT: retl 248; 249; X64-LABEL: ashr_add_shl_i36: 250; X64: # %bb.0: 251; X64-NEXT: movq %rdi, %rax 252; X64-NEXT: shlq $36, %rax 253; X64-NEXT: sarq $36, %rax 254; X64-NEXT: retq 255 %conv = shl i64 %r, 36 256 %sext = add i64 %conv, 4294967296 257 %conv1 = ashr i64 %sext, 36 258 ret i64 %conv1 259} 260 261define i64 @ashr_add_shl_mismatch_shifts1(i64 %r) nounwind { 262; X32-LABEL: ashr_add_shl_mismatch_shifts1: 263; X32: # %bb.0: 264; X32-NEXT: movl {{[0-9]+}}(%esp), %eax 265; X32-NEXT: incl %eax 266; X32-NEXT: movl %eax, %edx 267; X32-NEXT: sarl $31, %edx 268; X32-NEXT: retl 269; 270; X64-LABEL: ashr_add_shl_mismatch_shifts1: 271; X64: # %bb.0: 272; X64-NEXT: shlq $8, %rdi 273; X64-NEXT: movabsq $4294967296, %rax # imm = 0x100000000 274; X64-NEXT: addq %rdi, %rax 275; X64-NEXT: sarq $32, %rax 276; X64-NEXT: retq 277 %conv = shl i64 %r, 8 278 %sext = add i64 %conv, 4294967296 279 %conv1 = ashr i64 %sext, 32 280 ret i64 %conv1 281} 282 283define i64 @ashr_add_shl_mismatch_shifts2(i64 %r) nounwind { 284; X32-LABEL: ashr_add_shl_mismatch_shifts2: 285; X32: # %bb.0: 286; X32-NEXT: movl {{[0-9]+}}(%esp), %eax 287; X32-NEXT: movl {{[0-9]+}}(%esp), %edx 288; X32-NEXT: shrl $8, %edx 289; X32-NEXT: incl %edx 290; X32-NEXT: shrdl $8, %edx, %eax 291; X32-NEXT: shrl $8, %edx 292; X32-NEXT: retl 293; 294; X64-LABEL: ashr_add_shl_mismatch_shifts2: 295; X64: # %bb.0: 296; X64-NEXT: shrq $8, %rdi 297; X64-NEXT: movabsq $4294967296, %rax # imm = 0x100000000 298; X64-NEXT: addq %rdi, %rax 299; X64-NEXT: shrq $8, %rax 300; X64-NEXT: retq 301 %conv = lshr i64 %r, 8 302 %sext = add i64 %conv, 4294967296 303 %conv1 = ashr i64 %sext, 8 304 ret i64 %conv1 305} 306 307define dso_local i32 @ashr_add_shl_i32_i8_extra_use1(i32 %r, ptr %p) nounwind { 308; X32-LABEL: ashr_add_shl_i32_i8_extra_use1: 309; X32: # %bb.0: 310; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx 311; X32-NEXT: movl {{[0-9]+}}(%esp), %eax 312; X32-NEXT: shll $24, %eax 313; X32-NEXT: addl $33554432, %eax # imm = 0x2000000 314; X32-NEXT: movl %eax, (%ecx) 315; X32-NEXT: sarl $24, %eax 316; X32-NEXT: retl 317; 318; X64-LABEL: ashr_add_shl_i32_i8_extra_use1: 319; X64: # %bb.0: 320; X64-NEXT: # kill: def $edi killed $edi def $rdi 321; X64-NEXT: shll $24, %edi 322; X64-NEXT: leal 33554432(%rdi), %eax 323; X64-NEXT: movl %eax, (%rsi) 324; X64-NEXT: sarl $24, %eax 325; X64-NEXT: retq 326 %conv = shl i32 %r, 24 327 %sext = add i32 %conv, 33554432 328 store i32 %sext, ptr %p 329 %conv1 = ashr i32 %sext, 24 330 ret i32 %conv1 331} 332 333define dso_local i32 @ashr_add_shl_i32_i8_extra_use2(i32 %r, ptr %p) nounwind { 334; X32-LABEL: ashr_add_shl_i32_i8_extra_use2: 335; X32: # %bb.0: 336; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx 337; X32-NEXT: movl {{[0-9]+}}(%esp), %eax 338; X32-NEXT: shll $24, %eax 339; X32-NEXT: movl %eax, (%ecx) 340; X32-NEXT: addl $33554432, %eax # imm = 0x2000000 341; X32-NEXT: sarl $24, %eax 342; X32-NEXT: retl 343; 344; X64-LABEL: ashr_add_shl_i32_i8_extra_use2: 345; X64: # %bb.0: 346; X64-NEXT: # kill: def $edi killed $edi def $rdi 347; X64-NEXT: shll $24, %edi 348; X64-NEXT: movl %edi, (%rsi) 349; X64-NEXT: leal 33554432(%rdi), %eax 350; X64-NEXT: sarl $24, %eax 351; X64-NEXT: retq 352 %conv = shl i32 %r, 24 353 store i32 %conv, ptr %p 354 %sext = add i32 %conv, 33554432 355 %conv1 = ashr i32 %sext, 24 356 ret i32 %conv1 357} 358 359define dso_local i32 @ashr_add_shl_i32_i8_extra_use3(i32 %r, ptr %p1, ptr %p2) nounwind { 360; X32-LABEL: ashr_add_shl_i32_i8_extra_use3: 361; X32: # %bb.0: 362; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx 363; X32-NEXT: movl {{[0-9]+}}(%esp), %edx 364; X32-NEXT: movl {{[0-9]+}}(%esp), %eax 365; X32-NEXT: shll $24, %eax 366; X32-NEXT: movl %eax, (%edx) 367; X32-NEXT: addl $33554432, %eax # imm = 0x2000000 368; X32-NEXT: movl %eax, (%ecx) 369; X32-NEXT: sarl $24, %eax 370; X32-NEXT: retl 371; 372; X64-LABEL: ashr_add_shl_i32_i8_extra_use3: 373; X64: # %bb.0: 374; X64-NEXT: # kill: def $edi killed $edi def $rdi 375; X64-NEXT: shll $24, %edi 376; X64-NEXT: movl %edi, (%rsi) 377; X64-NEXT: leal 33554432(%rdi), %eax 378; X64-NEXT: movl %eax, (%rdx) 379; X64-NEXT: sarl $24, %eax 380; X64-NEXT: retq 381 %conv = shl i32 %r, 24 382 store i32 %conv, ptr %p1 383 %sext = add i32 %conv, 33554432 384 store i32 %sext, ptr %p2 385 %conv1 = ashr i32 %sext, 24 386 ret i32 %conv1 387} 388 389%"class.QPainterPath" = type { double, double, i32 } 390 391define dso_local void @PR42880(i32 %t0) { 392; X32-LABEL: PR42880: 393; X32: # %bb.0: 394; X32-NEXT: xorl %eax, %eax 395; X32-NEXT: testb %al, %al 396; X32-NEXT: je .LBB16_1 397; X32-NEXT: # %bb.2: # %if 398; X32-NEXT: .LBB16_1: # %then 399; 400; X64-LABEL: PR42880: 401; X64: # %bb.0: 402; X64-NEXT: xorl %eax, %eax 403; X64-NEXT: testb %al, %al 404; X64-NEXT: je .LBB16_1 405; X64-NEXT: # %bb.2: # %if 406; X64-NEXT: .LBB16_1: # %then 407 %sub = add nsw i32 %t0, -1 408 %add.ptr.i94 = getelementptr inbounds %"class.QPainterPath", ptr null, i32 %sub 409 %x = ptrtoint ptr %add.ptr.i94 to i32 410 %sub2 = sub i32 %x, 0 411 %div = sdiv exact i32 %sub2, 24 412 br i1 undef, label %if, label %then 413 414then: 415 %t1 = xor i32 %div, -1 416 unreachable 417 418if: 419 unreachable 420} 421 422; The mul here is the equivalent of (neg (shl X, 32)). 423define i64 @ashr_add_neg_shl_i32(i64 %r) nounwind { 424; X32-LABEL: ashr_add_neg_shl_i32: 425; X32: # %bb.0: 426; X32-NEXT: movl $1, %eax 427; X32-NEXT: subl {{[0-9]+}}(%esp), %eax 428; X32-NEXT: movl %eax, %edx 429; X32-NEXT: sarl $31, %edx 430; X32-NEXT: retl 431; 432; X64-LABEL: ashr_add_neg_shl_i32: 433; X64: # %bb.0: 434; X64-NEXT: movl $1, %eax 435; X64-NEXT: subl %edi, %eax 436; X64-NEXT: cltq 437; X64-NEXT: retq 438 %conv = mul i64 %r, -4294967296 439 %sext = add i64 %conv, 4294967296 440 %conv1 = ashr i64 %sext, 32 441 ret i64 %conv1 442} 443 444; The mul here is the equivalent of (neg (shl X, 56)). 445define i64 @ashr_add_neg_shl_i8(i64 %r) nounwind { 446; X32-LABEL: ashr_add_neg_shl_i8: 447; X32: # %bb.0: 448; X32-NEXT: movl {{[0-9]+}}(%esp), %eax 449; X32-NEXT: shll $24, %eax 450; X32-NEXT: movl $33554432, %edx # imm = 0x2000000 451; X32-NEXT: subl %eax, %edx 452; X32-NEXT: movl %edx, %eax 453; X32-NEXT: sarl $24, %eax 454; X32-NEXT: sarl $31, %edx 455; X32-NEXT: retl 456; 457; X64-LABEL: ashr_add_neg_shl_i8: 458; X64: # %bb.0: 459; X64-NEXT: movb $2, %al 460; X64-NEXT: subb %dil, %al 461; X64-NEXT: movsbq %al, %rax 462; X64-NEXT: retq 463 %conv = mul i64 %r, -72057594037927936 464 %sext = add i64 %conv, 144115188075855872 465 %conv1 = ashr i64 %sext, 56 466 ret i64 %conv1 467} 468 469; The mul here is the equivalent of (neg (shl X, 24)). 470define <4 x i32> @ashr_add_neg_shl_v4i8(<4 x i32> %r) nounwind { 471; X32-LABEL: ashr_add_neg_shl_v4i8: 472; X32: # %bb.0: 473; X32-NEXT: pushl %edi 474; X32-NEXT: pushl %esi 475; X32-NEXT: movl {{[0-9]+}}(%esp), %eax 476; X32-NEXT: movb $1, %cl 477; X32-NEXT: movb $1, %dl 478; X32-NEXT: subb {{[0-9]+}}(%esp), %dl 479; X32-NEXT: movsbl %dl, %edx 480; X32-NEXT: movb $1, %ch 481; X32-NEXT: subb {{[0-9]+}}(%esp), %ch 482; X32-NEXT: movsbl %ch, %esi 483; X32-NEXT: movb $1, %ch 484; X32-NEXT: subb {{[0-9]+}}(%esp), %ch 485; X32-NEXT: movsbl %ch, %edi 486; X32-NEXT: subb {{[0-9]+}}(%esp), %cl 487; X32-NEXT: movsbl %cl, %ecx 488; X32-NEXT: movl %ecx, 12(%eax) 489; X32-NEXT: movl %edi, 8(%eax) 490; X32-NEXT: movl %esi, 4(%eax) 491; X32-NEXT: movl %edx, (%eax) 492; X32-NEXT: popl %esi 493; X32-NEXT: popl %edi 494; X32-NEXT: retl $4 495; 496; X64-LABEL: ashr_add_neg_shl_v4i8: 497; X64: # %bb.0: 498; X64-NEXT: pslld $24, %xmm0 499; X64-NEXT: movdqa {{.*#+}} xmm1 = [16777216,16777216,16777216,16777216] 500; X64-NEXT: psubd %xmm0, %xmm1 501; X64-NEXT: psrad $24, %xmm1 502; X64-NEXT: movdqa %xmm1, %xmm0 503; X64-NEXT: retq 504 %conv = mul <4 x i32> %r, <i32 -16777216, i32 -16777216, i32 -16777216, i32 -16777216> 505 %sext = add <4 x i32> %conv, <i32 16777216, i32 16777216, i32 16777216, i32 16777216> 506 %conv1 = ashr <4 x i32> %sext, <i32 24, i32 24, i32 24, i32 24> 507 ret <4 x i32> %conv1 508} 509