462 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s -check-prefix=CHECK -check-prefix=ENABLED3; RUN: llc --disable-x86-lea-opt < %s -mtriple=x86_64-linux | FileCheck %s -check-prefix=CHECK -check-prefix=DISABLED4 5%struct.anon1 = type { i32, i32, i32 }6%struct.anon2 = type { i32, [32 x i32], i32 }7 8@arr1 = external dso_local global [65 x %struct.anon1], align 169@arr2 = external dso_local global [65 x %struct.anon2], align 1610 11define void @test1(i64 %x) nounwind {12; ENABLED-LABEL: test1:13; ENABLED: # %bb.0: # %entry14; ENABLED-NEXT: shlq $2, %rdi15; ENABLED-NEXT: movl arr1(%rdi,%rdi,2), %ecx16; ENABLED-NEXT: leaq arr1+4(%rdi,%rdi,2), %rax17; ENABLED-NEXT: subl arr1+4(%rdi,%rdi,2), %ecx18; ENABLED-NEXT: addl arr1+8(%rdi,%rdi,2), %ecx19; ENABLED-NEXT: cmpl $2, %ecx20; ENABLED-NEXT: je .LBB0_321; ENABLED-NEXT: # %bb.1: # %entry22; ENABLED-NEXT: cmpl $1, %ecx23; ENABLED-NEXT: jne .LBB0_424; ENABLED-NEXT: # %bb.2: # %sw.bb.125; ENABLED-NEXT: movl $111, (%rax)26; ENABLED-NEXT: movl $222, 4(%rax)27; ENABLED-NEXT: retq28; ENABLED-NEXT: .LBB0_3: # %sw.bb.229; ENABLED-NEXT: movl $333, (%rax) # imm = 0x14D30; ENABLED-NEXT: movl $444, 4(%rax) # imm = 0x1BC31; ENABLED-NEXT: .LBB0_4: # %sw.epilog32; ENABLED-NEXT: retq33;34; DISABLED-LABEL: test1:35; DISABLED: # %bb.0: # %entry36; DISABLED-NEXT: shlq $2, %rdi37; DISABLED-NEXT: movl arr1(%rdi,%rdi,2), %edx38; DISABLED-NEXT: leaq arr1+4(%rdi,%rdi,2), %rax39; DISABLED-NEXT: subl arr1+4(%rdi,%rdi,2), %edx40; DISABLED-NEXT: leaq arr1+8(%rdi,%rdi,2), %rcx41; DISABLED-NEXT: addl arr1+8(%rdi,%rdi,2), %edx42; DISABLED-NEXT: cmpl $2, %edx43; DISABLED-NEXT: je .LBB0_344; DISABLED-NEXT: # %bb.1: # %entry45; DISABLED-NEXT: cmpl $1, %edx46; DISABLED-NEXT: jne .LBB0_447; DISABLED-NEXT: # %bb.2: # %sw.bb.148; DISABLED-NEXT: movl $111, (%rax)49; DISABLED-NEXT: movl $222, (%rcx)50; DISABLED-NEXT: retq51; DISABLED-NEXT: .LBB0_3: # %sw.bb.252; DISABLED-NEXT: movl $333, (%rax) # imm = 0x14D53; DISABLED-NEXT: movl $444, (%rcx) # imm = 0x1BC54; DISABLED-NEXT: .LBB0_4: # %sw.epilog55; DISABLED-NEXT: retq56entry:57 %a = getelementptr inbounds [65 x %struct.anon1], ptr @arr1, i64 0, i64 %x, i32 058 %tmp = load i32, ptr %a, align 459 %b = getelementptr inbounds [65 x %struct.anon1], ptr @arr1, i64 0, i64 %x, i32 160 %tmp1 = load i32, ptr %b, align 461 %sub = sub i32 %tmp, %tmp162 %c = getelementptr inbounds [65 x %struct.anon1], ptr @arr1, i64 0, i64 %x, i32 263 %tmp2 = load i32, ptr %c, align 464 %add = add nsw i32 %sub, %tmp265 switch i32 %add, label %sw.epilog [66 i32 1, label %sw.bb.167 i32 2, label %sw.bb.268 ]69 70sw.bb.1: ; preds = %entry71 store i32 111, ptr %b, align 472 store i32 222, ptr %c, align 473 br label %sw.epilog74 75sw.bb.2: ; preds = %entry76 store i32 333, ptr %b, align 477 store i32 444, ptr %c, align 478 br label %sw.epilog79 80sw.epilog: ; preds = %sw.bb.2, %sw.bb.1, %entry81 ret void82}83 84define void @test2(i64 %x) nounwind optsize {85; ENABLED-LABEL: test2:86; ENABLED: # %bb.0: # %entry87; ENABLED-NEXT: shlq $2, %rdi88; ENABLED-NEXT: leaq arr1+4(%rdi,%rdi,2), %rax89; ENABLED-NEXT: movl -4(%rax), %ecx90; ENABLED-NEXT: subl (%rax), %ecx91; ENABLED-NEXT: addl 4(%rax), %ecx92; ENABLED-NEXT: cmpl $2, %ecx93; ENABLED-NEXT: je .LBB1_394; ENABLED-NEXT: # %bb.1: # %entry95; ENABLED-NEXT: cmpl $1, %ecx96; ENABLED-NEXT: jne .LBB1_497; ENABLED-NEXT: # %bb.2: # %sw.bb.198; ENABLED-NEXT: movl $111, (%rax)99; ENABLED-NEXT: movl $222, 4(%rax)100; ENABLED-NEXT: retq101; ENABLED-NEXT: .LBB1_3: # %sw.bb.2102; ENABLED-NEXT: movl $333, (%rax) # imm = 0x14D103; ENABLED-NEXT: movl $444, 4(%rax) # imm = 0x1BC104; ENABLED-NEXT: .LBB1_4: # %sw.epilog105; ENABLED-NEXT: retq106;107; DISABLED-LABEL: test2:108; DISABLED: # %bb.0: # %entry109; DISABLED-NEXT: shlq $2, %rdi110; DISABLED-NEXT: movl arr1(%rdi,%rdi,2), %edx111; DISABLED-NEXT: leaq arr1+4(%rdi,%rdi,2), %rax112; DISABLED-NEXT: subl arr1+4(%rdi,%rdi,2), %edx113; DISABLED-NEXT: leaq arr1+8(%rdi,%rdi,2), %rcx114; DISABLED-NEXT: addl arr1+8(%rdi,%rdi,2), %edx115; DISABLED-NEXT: cmpl $2, %edx116; DISABLED-NEXT: je .LBB1_3117; DISABLED-NEXT: # %bb.1: # %entry118; DISABLED-NEXT: cmpl $1, %edx119; DISABLED-NEXT: jne .LBB1_4120; DISABLED-NEXT: # %bb.2: # %sw.bb.1121; DISABLED-NEXT: movl $111, (%rax)122; DISABLED-NEXT: movl $222, (%rcx)123; DISABLED-NEXT: retq124; DISABLED-NEXT: .LBB1_3: # %sw.bb.2125; DISABLED-NEXT: movl $333, (%rax) # imm = 0x14D126; DISABLED-NEXT: movl $444, (%rcx) # imm = 0x1BC127; DISABLED-NEXT: .LBB1_4: # %sw.epilog128; DISABLED-NEXT: retq129entry:130 %a = getelementptr inbounds [65 x %struct.anon1], ptr @arr1, i64 0, i64 %x, i32 0131 %tmp = load i32, ptr %a, align 4132 %b = getelementptr inbounds [65 x %struct.anon1], ptr @arr1, i64 0, i64 %x, i32 1133 %tmp1 = load i32, ptr %b, align 4134 %sub = sub i32 %tmp, %tmp1135 %c = getelementptr inbounds [65 x %struct.anon1], ptr @arr1, i64 0, i64 %x, i32 2136 %tmp2 = load i32, ptr %c, align 4137 %add = add nsw i32 %sub, %tmp2138 switch i32 %add, label %sw.epilog [139 i32 1, label %sw.bb.1140 i32 2, label %sw.bb.2141 ]142 143sw.bb.1: ; preds = %entry144 store i32 111, ptr %b, align 4145 store i32 222, ptr %c, align 4146 br label %sw.epilog147 148sw.bb.2: ; preds = %entry149 store i32 333, ptr %b, align 4150 store i32 444, ptr %c, align 4151 br label %sw.epilog152 153sw.epilog: ; preds = %sw.bb.2, %sw.bb.1, %entry154 ret void155}156 157; Check that LEA optimization pass takes into account a resultant address158; displacement when choosing a LEA instruction for replacing a redundant159; address recalculation.160 161define void @test3(i64 %x) nounwind optsize {162; ENABLED-LABEL: test3:163; ENABLED: # %bb.0: # %entry164; ENABLED-NEXT: movq %rdi, %rax165; ENABLED-NEXT: shlq $7, %rax166; ENABLED-NEXT: leaq arr2+132(%rax,%rdi,8), %rcx167; ENABLED-NEXT: leaq arr2(%rax,%rdi,8), %rax168; ENABLED-NEXT: movl (%rcx), %edx169; ENABLED-NEXT: addl (%rax), %edx170; ENABLED-NEXT: cmpl $2, %edx171; ENABLED-NEXT: je .LBB2_3172; ENABLED-NEXT: # %bb.1: # %entry173; ENABLED-NEXT: cmpl $1, %edx174; ENABLED-NEXT: jne .LBB2_4175; ENABLED-NEXT: # %bb.2: # %sw.bb.1176; ENABLED-NEXT: movl $111, (%rcx)177; ENABLED-NEXT: movl $222, (%rax)178; ENABLED-NEXT: retq179; ENABLED-NEXT: .LBB2_3: # %sw.bb.2180; ENABLED-NEXT: movl $333, (%rcx) # imm = 0x14D181; ENABLED-NEXT: movl %eax, (%rax)182; ENABLED-NEXT: .LBB2_4: # %sw.epilog183; ENABLED-NEXT: retq184;185; DISABLED-LABEL: test3:186; DISABLED: # %bb.0: # %entry187; DISABLED-NEXT: movq %rdi, %rsi188; DISABLED-NEXT: shlq $7, %rsi189; DISABLED-NEXT: leaq arr2+132(%rsi,%rdi,8), %rcx190; DISABLED-NEXT: leaq arr2(%rsi,%rdi,8), %rax191; DISABLED-NEXT: movl arr2+132(%rsi,%rdi,8), %edx192; DISABLED-NEXT: addl arr2(%rsi,%rdi,8), %edx193; DISABLED-NEXT: cmpl $2, %edx194; DISABLED-NEXT: je .LBB2_3195; DISABLED-NEXT: # %bb.1: # %entry196; DISABLED-NEXT: cmpl $1, %edx197; DISABLED-NEXT: jne .LBB2_4198; DISABLED-NEXT: # %bb.2: # %sw.bb.1199; DISABLED-NEXT: movl $111, (%rcx)200; DISABLED-NEXT: movl $222, (%rax)201; DISABLED-NEXT: retq202; DISABLED-NEXT: .LBB2_3: # %sw.bb.2203; DISABLED-NEXT: movl $333, (%rcx) # imm = 0x14D204; DISABLED-NEXT: movl %eax, (%rax)205; DISABLED-NEXT: .LBB2_4: # %sw.epilog206; DISABLED-NEXT: retq207entry:208 %a = getelementptr inbounds [65 x %struct.anon2], ptr @arr2, i64 0, i64 %x, i32 2209 %tmp = load i32, ptr %a, align 4210 %b = getelementptr inbounds [65 x %struct.anon2], ptr @arr2, i64 0, i64 %x, i32 0211 %tmp1 = load i32, ptr %b, align 4212 %add = add nsw i32 %tmp, %tmp1213 switch i32 %add, label %sw.epilog [214 i32 1, label %sw.bb.1215 i32 2, label %sw.bb.2216 ]217 218sw.bb.1: ; preds = %entry219 store i32 111, ptr %a, align 4220 store i32 222, ptr %b, align 4221 br label %sw.epilog222 223sw.bb.2: ; preds = %entry224 store i32 333, ptr %a, align 4225 ; Make sure the REG3's definition LEA won't be removed as redundant.226 %cvt = ptrtoint ptr %b to i32227 store i32 %cvt, ptr %b, align 4228 br label %sw.epilog229 230sw.epilog: ; preds = %sw.bb.2, %sw.bb.1, %entry231 ret void232 233; REG3's definition is closer to movl than REG2's, but the pass still chooses234; REG2 because it provides the resultant address displacement fitting 1 byte.235 236}237 238define void @test4(i64 %x) nounwind minsize {239; ENABLED-LABEL: test4:240; ENABLED: # %bb.0: # %entry241; ENABLED-NEXT: imulq $12, %rdi, %rax242; ENABLED-NEXT: leaq arr1+4(%rax), %rax243; ENABLED-NEXT: movl -4(%rax), %ecx244; ENABLED-NEXT: subl (%rax), %ecx245; ENABLED-NEXT: addl 4(%rax), %ecx246; ENABLED-NEXT: cmpl $2, %ecx247; ENABLED-NEXT: je .LBB3_3248; ENABLED-NEXT: # %bb.1: # %entry249; ENABLED-NEXT: cmpl $1, %ecx250; ENABLED-NEXT: jne .LBB3_4251; ENABLED-NEXT: # %bb.2: # %sw.bb.1252; ENABLED-NEXT: movl $111, (%rax)253; ENABLED-NEXT: movl $222, 4(%rax)254; ENABLED-NEXT: retq255; ENABLED-NEXT: .LBB3_3: # %sw.bb.2256; ENABLED-NEXT: movl $333, (%rax) # imm = 0x14D257; ENABLED-NEXT: movl $444, 4(%rax) # imm = 0x1BC258; ENABLED-NEXT: .LBB3_4: # %sw.epilog259; ENABLED-NEXT: retq260;261; DISABLED-LABEL: test4:262; DISABLED: # %bb.0: # %entry263; DISABLED-NEXT: imulq $12, %rdi, %rsi264; DISABLED-NEXT: movl arr1(%rsi), %edx265; DISABLED-NEXT: leaq arr1+4(%rsi), %rax266; DISABLED-NEXT: subl arr1+4(%rsi), %edx267; DISABLED-NEXT: leaq arr1+8(%rsi), %rcx268; DISABLED-NEXT: addl arr1+8(%rsi), %edx269; DISABLED-NEXT: cmpl $2, %edx270; DISABLED-NEXT: je .LBB3_3271; DISABLED-NEXT: # %bb.1: # %entry272; DISABLED-NEXT: cmpl $1, %edx273; DISABLED-NEXT: jne .LBB3_4274; DISABLED-NEXT: # %bb.2: # %sw.bb.1275; DISABLED-NEXT: movl $111, (%rax)276; DISABLED-NEXT: movl $222, (%rcx)277; DISABLED-NEXT: retq278; DISABLED-NEXT: .LBB3_3: # %sw.bb.2279; DISABLED-NEXT: movl $333, (%rax) # imm = 0x14D280; DISABLED-NEXT: movl $444, (%rcx) # imm = 0x1BC281; DISABLED-NEXT: .LBB3_4: # %sw.epilog282; DISABLED-NEXT: retq283entry:284 %a = getelementptr inbounds [65 x %struct.anon1], ptr @arr1, i64 0, i64 %x, i32 0285 %tmp = load i32, ptr %a, align 4286 %b = getelementptr inbounds [65 x %struct.anon1], ptr @arr1, i64 0, i64 %x, i32 1287 %tmp1 = load i32, ptr %b, align 4288 %sub = sub i32 %tmp, %tmp1289 %c = getelementptr inbounds [65 x %struct.anon1], ptr @arr1, i64 0, i64 %x, i32 2290 %tmp2 = load i32, ptr %c, align 4291 %add = add nsw i32 %sub, %tmp2292 switch i32 %add, label %sw.epilog [293 i32 1, label %sw.bb.1294 i32 2, label %sw.bb.2295 ]296 297sw.bb.1: ; preds = %entry298 store i32 111, ptr %b, align 4299 store i32 222, ptr %c, align 4300 br label %sw.epilog301 302sw.bb.2: ; preds = %entry303 store i32 333, ptr %b, align 4304 store i32 444, ptr %c, align 4305 br label %sw.epilog306 307sw.epilog: ; preds = %sw.bb.2, %sw.bb.1, %entry308 ret void309}310 311define i32 @test5(i32 %x, i32 %y) #0 {312; CHECK-LABEL: test5:313; CHECK: # %bb.0: # %entry314; CHECK-NEXT: movl %edi, %eax315; CHECK-NEXT: addl %esi, %esi316; CHECK-NEXT: subl %esi, %eax317; CHECK-NEXT: retq318entry:319 %mul = mul nsw i32 %y, -2320 %add = add nsw i32 %mul, %x321 ret i32 %add322}323 324define i32 @test6(i32 %x, i32 %y) #0 {325; CHECK-LABEL: test6:326; CHECK: # %bb.0: # %entry327; CHECK-NEXT: # kill: def $esi killed $esi def $rsi328; CHECK-NEXT: movl %edi, %eax329; CHECK-NEXT: leal (%rsi,%rsi,2), %ecx330; CHECK-NEXT: subl %ecx, %eax331; CHECK-NEXT: retq332entry:333 %mul = mul nsw i32 %y, -3334 %add = add nsw i32 %mul, %x335 ret i32 %add336}337 338define i32 @test7(i32 %x, i32 %y) #0 {339; CHECK-LABEL: test7:340; CHECK: # %bb.0: # %entry341; CHECK-NEXT: movl %edi, %eax342; CHECK-NEXT: shll $2, %esi343; CHECK-NEXT: subl %esi, %eax344; CHECK-NEXT: retq345entry:346 %mul = mul nsw i32 %y, -4347 %add = add nsw i32 %mul, %x348 ret i32 %add349}350 351define i32 @test8(i32 %x, i32 %y) #0 {352; CHECK-LABEL: test8:353; CHECK: # %bb.0: # %entry354; CHECK-NEXT: # kill: def $esi killed $esi def $rsi355; CHECK-NEXT: leal (,%rsi,4), %eax356; CHECK-NEXT: subl %edi, %eax357; CHECK-NEXT: retq358entry:359 %mul = shl nsw i32 %y, 2360 %sub = sub nsw i32 %mul, %x361 ret i32 %sub362}363 364 365define i32 @test9(i32 %x, i32 %y) #0 {366; CHECK-LABEL: test9:367; CHECK: # %bb.0: # %entry368; CHECK-NEXT: movl %edi, %eax369; CHECK-NEXT: addl %esi, %esi370; CHECK-NEXT: subl %esi, %eax371; CHECK-NEXT: retq372entry:373 %mul = mul nsw i32 -2, %y374 %add = add nsw i32 %x, %mul375 ret i32 %add376}377 378define i32 @test10(i32 %x, i32 %y) #0 {379; CHECK-LABEL: test10:380; CHECK: # %bb.0: # %entry381; CHECK-NEXT: # kill: def $esi killed $esi def $rsi382; CHECK-NEXT: movl %edi, %eax383; CHECK-NEXT: leal (%rsi,%rsi,2), %ecx384; CHECK-NEXT: subl %ecx, %eax385; CHECK-NEXT: retq386entry:387 %mul = mul nsw i32 -3, %y388 %add = add nsw i32 %x, %mul389 ret i32 %add390}391 392define i32 @test11(i32 %x, i32 %y) #0 {393; CHECK-LABEL: test11:394; CHECK: # %bb.0: # %entry395; CHECK-NEXT: movl %edi, %eax396; CHECK-NEXT: shll $2, %esi397; CHECK-NEXT: subl %esi, %eax398; CHECK-NEXT: retq399entry:400 %mul = mul nsw i32 -4, %y401 %add = add nsw i32 %x, %mul402 ret i32 %add403}404 405define i32 @test12(i32 %x, i32 %y) #0 {406; CHECK-LABEL: test12:407; CHECK: # %bb.0: # %entry408; CHECK-NEXT: # kill: def $esi killed $esi def $rsi409; CHECK-NEXT: leal (,%rsi,4), %eax410; CHECK-NEXT: subl %edi, %eax411; CHECK-NEXT: retq412entry:413 %mul = mul nsw i32 4, %y414 %sub = sub nsw i32 %mul, %x415 ret i32 %sub416}417 418define i64 @test13(i64 %x, i64 %y) #0 {419; CHECK-LABEL: test13:420; CHECK: # %bb.0: # %entry421; CHECK-NEXT: movq %rdi, %rax422; CHECK-NEXT: shlq $2, %rsi423; CHECK-NEXT: subq %rsi, %rax424; CHECK-NEXT: retq425entry:426 %mul = mul nsw i64 -4, %y427 %add = add nsw i64 %x, %mul428 ret i64 %add429}430 431define i32 @test14(i32 %x, i32 %y) #0 {432; CHECK-LABEL: test14:433; CHECK: # %bb.0: # %entry434; CHECK-NEXT: # kill: def $esi killed $esi def $rsi435; CHECK-NEXT: leal (,%rsi,4), %eax436; CHECK-NEXT: subl %edi, %eax437; CHECK-NEXT: retq438entry:439 %mul = mul nsw i32 4, %y440 %sub = sub nsw i32 %mul, %x441 ret i32 %sub442}443 444define zeroext i16 @test15(i16 zeroext %x, i16 zeroext %y) #0 {445; CHECK-LABEL: test15:446; CHECK: # %bb.0: # %entry447; CHECK-NEXT: movl %edi, %eax448; CHECK-NEXT: shll $3, %esi449; CHECK-NEXT: subl %esi, %eax450; CHECK-NEXT: # kill: def $ax killed $ax killed $eax451; CHECK-NEXT: retq452entry:453 %conv = zext i16 %x to i32454 %conv1 = zext i16 %y to i32455 %mul = mul nsw i32 -8, %conv1456 %add = add nsw i32 %conv, %mul457 %conv2 = trunc i32 %add to i16458 ret i16 %conv2459}460 461attributes #0 = { norecurse nounwind optsize readnone uwtable}462