# RUN: llc -run-pass x86-fixup-LEAs -mtriple=i386 -verify-machineinstrs -mcpu=corei7-avx -o - %s | FileCheck %s --- | ; ModuleID = 'test/CodeGen/X86/fixup-lea.ll' source_filename = "test/CodeGen/X86/fixup-lea.ll" target datalayout = "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128" target triple = "i386" ;generated using: llc -stop-after x86-pad-short-functions fixup-lea.ll > leaFinxup32.mir ;test2add_32: 3 operands LEA32r that can be replaced with 2 add instructions ; where ADD32ri8 is chosen define i32 @test2add_32() { ret i32 0 } ;test2add_ebp_32: 3 operands LEA32r that can be replaced with 2 add instructions ; where the base is rbp/r13/ebp register define i32 @test2add_ebp_32() { ret i32 0 } ;test1add_ebp_32: 2 operands LEA32r where base register is ebp and can be replaced ; with an add instruction define i32 @test1add_ebp_32() { ret i32 0 } ;testleaadd_32: 3 operands LEA32r that can be replaced with 1 lea 1 add instructions define i32 @testleaadd_32() { ret i32 0 } ;testleaadd_ebp_32: 3 operands LEA32r that can be replaced with 1 lea 1 add instructions ; where the base is ebp register define i32 @testleaadd_ebp_32() { ret i32 0 } ;test1lea_ebp_32: 2 operands LEA32r wher base register is rbp/r13/ebp and can be replaced ; with a lea instruction define i32 @test1lea_ebp_32() { ret i32 0 } ;test2addi32_32: 3 operands LEA32r that can be replaced with 2 add instructions where ADD32ri32 ; is chosen define i32 @test2addi32_32() { ret i32 0 } ;test1mov1add_ebp_32: 2 operands LEA32r that can be replaced with 1 add 1 mov instructions ; where the base is rbp/r13/ebp register define i32 @test1mov1add_ebp_32() { ret i32 0 } ;testleaadd_ebp_index_32: 3 operands LEA32r that can be replaced with 1 lea 1 add instructions ; where the base and the index are ebp register and there is offset define i32 @testleaadd_ebp_index_32() { ret i32 0 } ;testleaadd_ebp_index2_32: 3 operands LEA32r that can be replaced with 1 lea 1 add instructions ; where the base and the index are ebp register and there is scale define i32 @testleaadd_ebp_index2_32() { ret i32 0 } ;test_skip_opt_32: 3 operands LEA32r that can not be replaced with 2 instructions define i32 @test_skip_opt_32() { ret i32 0 } ;test_skip_eflags_32: LEA32r that cannot be replaced since its not safe to clobber eflags define i32 @test_skip_eflags_32() { ret i32 0 } ... --- name: test2add_32 alignment: 4 exposesReturnsTwice: false legalized: false regBankSelected: false selected: false tracksRegLiveness: true liveins: - { reg: '%eax' } - { reg: '%ebp' } frameInfo: isFrameAddressTaken: false isReturnAddressTaken: false hasStackMap: false hasPatchPoint: false stackSize: 0 offsetAdjustment: 0 maxAlignment: 0 adjustsStack: false hasCalls: false maxCallFrameSize: 0 hasOpaqueSPAdjustment: false hasVAStart: false hasMustTailInVarArgFunc: false body: | bb.0 (%ir-block.0): liveins: %eax, %ebp ; CHECK: %eax = ADD32rr %eax, killed %ebp ; CHECK: %eax = ADD32ri8 %eax, -5 %eax = LEA32r killed %eax, 1, killed %ebp, -5, %noreg RETQ %eax ... --- name: test2add_ebp_32 alignment: 4 exposesReturnsTwice: false legalized: false regBankSelected: false selected: false tracksRegLiveness: true liveins: - { reg: '%eax' } - { reg: '%ebp' } frameInfo: isFrameAddressTaken: false isReturnAddressTaken: false hasStackMap: false hasPatchPoint: false stackSize: 0 offsetAdjustment: 0 maxAlignment: 0 adjustsStack: false hasCalls: false maxCallFrameSize: 0 hasOpaqueSPAdjustment: false hasVAStart: false hasMustTailInVarArgFunc: false body: | bb.0 (%ir-block.0): liveins: %eax, %ebp ; CHECK: %ebp = ADD32rr %ebp, killed %eax ; CHECK: %ebp = ADD32ri8 %ebp, -5 %ebp = LEA32r killed %ebp, 1, killed %eax, -5, %noreg RETQ %ebp ... --- name: test1add_ebp_32 alignment: 4 exposesReturnsTwice: false legalized: false regBankSelected: false selected: false tracksRegLiveness: true liveins: - { reg: '%eax' } - { reg: '%ebp' } frameInfo: isFrameAddressTaken: false isReturnAddressTaken: false hasStackMap: false hasPatchPoint: false stackSize: 0 offsetAdjustment: 0 maxAlignment: 0 adjustsStack: false hasCalls: false maxCallFrameSize: 0 hasOpaqueSPAdjustment: false hasVAStart: false hasMustTailInVarArgFunc: false body: | bb.0 (%ir-block.0): liveins: %eax, %ebp ; CHECK: %ebp = ADD32rr %ebp, killed %eax %ebp = LEA32r killed %ebp, 1, killed %eax, 0, %noreg RETQ %ebp ... --- name: testleaadd_32 alignment: 4 exposesReturnsTwice: false legalized: false regBankSelected: false selected: false tracksRegLiveness: true liveins: - { reg: '%eax' } - { reg: '%ebp' } - { reg: '%ebx' } frameInfo: isFrameAddressTaken: false isReturnAddressTaken: false hasStackMap: false hasPatchPoint: false stackSize: 0 offsetAdjustment: 0 maxAlignment: 0 adjustsStack: false hasCalls: false maxCallFrameSize: 0 hasOpaqueSPAdjustment: false hasVAStart: false hasMustTailInVarArgFunc: false body: | bb.0 (%ir-block.0): liveins: %eax, %ebp, %esi ; CHECK: %ebx = LEA32r killed %eax, 1, killed %ebp, 0 ; CHECK: %ebx = ADD32ri8 %ebx, -5 %ebx = LEA32r killed %eax, 1, killed %ebp, -5, %noreg RETQ %ebx ... --- name: testleaadd_ebp_32 alignment: 4 exposesReturnsTwice: false legalized: false regBankSelected: false selected: false tracksRegLiveness: true liveins: - { reg: '%eax' } - { reg: '%ebp' } - { reg: '%ebx' } frameInfo: isFrameAddressTaken: false isReturnAddressTaken: false hasStackMap: false hasPatchPoint: false stackSize: 0 offsetAdjustment: 0 maxAlignment: 0 adjustsStack: false hasCalls: false maxCallFrameSize: 0 hasOpaqueSPAdjustment: false hasVAStart: false hasMustTailInVarArgFunc: false body: | bb.0 (%ir-block.0): liveins: %eax, %ebp ; CHECK: %ebx = LEA32r killed %eax, 1, killed %ebp, 0, %noreg ; CHECK: %ebx = ADD32ri8 %ebx, -5 %ebx = LEA32r killed %ebp, 1, killed %eax, -5, %noreg RETQ %ebx ... --- name: test1lea_ebp_32 alignment: 4 exposesReturnsTwice: false legalized: false regBankSelected: false selected: false tracksRegLiveness: true liveins: - { reg: '%eax' } - { reg: '%ebp' } - { reg: '%ebx' } frameInfo: isFrameAddressTaken: false isReturnAddressTaken: false hasStackMap: false hasPatchPoint: false stackSize: 0 offsetAdjustment: 0 maxAlignment: 0 adjustsStack: false hasCalls: false maxCallFrameSize: 0 hasOpaqueSPAdjustment: false hasVAStart: false hasMustTailInVarArgFunc: false body: | bb.0 (%ir-block.0): liveins: %eax, %ebp ; CHECK: %ebx = LEA32r killed %eax, 1, killed %ebp, 0, %noreg %ebx = LEA32r killed %ebp, 1, killed %eax, 0, %noreg RETQ %ebx ... --- name: test2addi32_32 alignment: 4 exposesReturnsTwice: false legalized: false regBankSelected: false selected: false tracksRegLiveness: true liveins: - { reg: '%eax' } - { reg: '%ebp' } frameInfo: isFrameAddressTaken: false isReturnAddressTaken: false hasStackMap: false hasPatchPoint: false stackSize: 0 offsetAdjustment: 0 maxAlignment: 0 adjustsStack: false hasCalls: false maxCallFrameSize: 0 hasOpaqueSPAdjustment: false hasVAStart: false hasMustTailInVarArgFunc: false body: | bb.0 (%ir-block.0): liveins: %eax, %ebp ; CHECK: %eax = ADD32rr %eax, killed %ebp ; CHECK: %eax = ADD32ri %eax, 129 %eax = LEA32r killed %eax, 1, killed %ebp, 129, %noreg RETQ %eax ... --- name: test1mov1add_ebp_32 alignment: 4 exposesReturnsTwice: false legalized: false regBankSelected: false selected: false tracksRegLiveness: true liveins: - { reg: '%eax' } - { reg: '%ebx' } - { reg: '%ebp' } frameInfo: isFrameAddressTaken: false isReturnAddressTaken: false hasStackMap: false hasPatchPoint: false stackSize: 0 offsetAdjustment: 0 maxAlignment: 0 adjustsStack: false hasCalls: false maxCallFrameSize: 0 hasOpaqueSPAdjustment: false hasVAStart: false hasMustTailInVarArgFunc: false body: | bb.0 (%ir-block.0): liveins: %eax, %ebp, %ebx ; CHECK: %ebx = MOV32rr %ebp ; CHECK: %ebx = ADD32rr %ebx, %ebp %ebx = LEA32r %ebp, 1, %ebp, 0, %noreg RETQ %ebx ... --- name: testleaadd_ebp_index_32 alignment: 4 exposesReturnsTwice: false legalized: false regBankSelected: false selected: false tracksRegLiveness: true liveins: - { reg: '%ebx' } - { reg: '%ebp' } frameInfo: isFrameAddressTaken: false isReturnAddressTaken: false hasStackMap: false hasPatchPoint: false stackSize: 0 offsetAdjustment: 0 maxAlignment: 0 adjustsStack: false hasCalls: false maxCallFrameSize: 0 hasOpaqueSPAdjustment: false hasVAStart: false hasMustTailInVarArgFunc: false body: | bb.0 (%ir-block.0): liveins: %eax, %ebp, %ebx ; CHECK: %ebx = LEA32r %noreg, 1, %ebp, 5, %noreg ; CHECK: %ebx = ADD32rr %ebx, %ebp %ebx = LEA32r %ebp, 1, %ebp, 5, %noreg RETQ %ebx ... --- name: testleaadd_ebp_index2_32 alignment: 4 exposesReturnsTwice: false legalized: false regBankSelected: false selected: false tracksRegLiveness: true liveins: - { reg: '%ebx' } - { reg: '%ebp' } frameInfo: isFrameAddressTaken: false isReturnAddressTaken: false hasStackMap: false hasPatchPoint: false stackSize: 0 offsetAdjustment: 0 maxAlignment: 0 adjustsStack: false hasCalls: false maxCallFrameSize: 0 hasOpaqueSPAdjustment: false hasVAStart: false hasMustTailInVarArgFunc: false body: | bb.0 (%ir-block.0): liveins: %eax, %ebp, %ebx ; CHECK: %ebx = LEA32r %noreg, 4, %ebp, 5, %noreg ; CHECK: %ebx = ADD32rr %ebx, %ebp %ebx = LEA32r %ebp, 4, %ebp, 5, %noreg RETQ %ebx ... --- name: test_skip_opt_32 alignment: 4 exposesReturnsTwice: false legalized: false regBankSelected: false selected: false tracksRegLiveness: true liveins: - { reg: '%ebx' } - { reg: '%ebp' } frameInfo: isFrameAddressTaken: false isReturnAddressTaken: false hasStackMap: false hasPatchPoint: false stackSize: 0 offsetAdjustment: 0 maxAlignment: 0 adjustsStack: false hasCalls: false maxCallFrameSize: 0 hasOpaqueSPAdjustment: false hasVAStart: false hasMustTailInVarArgFunc: false body: | bb.0 (%ir-block.0): liveins: %eax, %ebp, %ebx ; CHECK: %ebp = LEA32r killed %ebp, 4, killed %ebp, 0, %noreg %ebp = LEA32r killed %ebp, 4, killed %ebp, 0, %noreg RETQ %ebp ... --- name: test_skip_eflags_32 alignment: 4 exposesReturnsTwice: false legalized: false regBankSelected: false selected: false tracksRegLiveness: true liveins: - { reg: '%ebp' } - { reg: '%eax' } frameInfo: isFrameAddressTaken: false isReturnAddressTaken: false hasStackMap: false hasPatchPoint: false stackSize: 0 offsetAdjustment: 0 maxAlignment: 0 adjustsStack: false hasCalls: false maxCallFrameSize: 0 hasOpaqueSPAdjustment: false hasVAStart: false hasMustTailInVarArgFunc: false body: | bb.0 (%ir-block.0): liveins: %eax, %ebp, %ebx ; CHECK: %ebx = LEA32r killed %eax, 4, killed %eax, 5, %noreg ; CHECK: %ebp = LEA32r killed %ebx, 4, killed %ebx, 0, %noreg ; CHECK: %ebp = ADD32ri8 %ebp, 5 CMP32rr %eax, killed %ebx, implicit-def %eflags %ebx = LEA32r killed %eax, 4, killed %eax, 5, %noreg JE_1 %bb.1, implicit %eflags RETQ %ebx bb.1: liveins: %eax, %ebp, %ebx %ebp = LEA32r killed %ebx, 4, killed %ebx, 5, %noreg RETQ %ebp ...