From 11c3bab1a06746e2262eee58c27f950ffba4ef02 Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Wed, 15 Mar 2017 18:38:13 +0000 Subject: [PATCH 1/5] ARM: avoid clobbering register in v6 jump-table expansion. If we got unlucky with register allocation and actual constpool placement, we could end up producing a tTBB_JT with an index that's already been clobbered. Technically, we might be able to fix this situation up with a MOV, but I think the constant islands pass is complex enough without having to deal with more weird edge-cases. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@297871 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/MIRYamlMapping.h | 2 + lib/CodeGen/MIRParser/MIRParser.cpp | 2 + lib/CodeGen/MIRPrinter.cpp | 2 + lib/Target/ARM/ARMConstantIslandPass.cpp | 14 +- test/CodeGen/ARM/v6-jumptable-clobber.mir | 384 ++++++++++++++++++ .../X86/GlobalISel/irtranslator-call.ll | 1 + 6 files changed, 401 insertions(+), 4 deletions(-) create mode 100644 test/CodeGen/ARM/v6-jumptable-clobber.mir diff --git a/include/llvm/CodeGen/MIRYamlMapping.h b/include/llvm/CodeGen/MIRYamlMapping.h index 778f72c06e65..e4b6f6119de2 100644 --- a/include/llvm/CodeGen/MIRYamlMapping.h +++ b/include/llvm/CodeGen/MIRYamlMapping.h @@ -381,6 +381,7 @@ struct MachineFunction { StringRef Name; unsigned Alignment = 0; bool ExposesReturnsTwice = false; + bool NoVRegs; // GISel MachineFunctionProperties. bool Legalized = false; bool RegBankSelected = false; @@ -405,6 +406,7 @@ template <> struct MappingTraits { YamlIO.mapRequired("name", MF.Name); YamlIO.mapOptional("alignment", MF.Alignment); YamlIO.mapOptional("exposesReturnsTwice", MF.ExposesReturnsTwice); + YamlIO.mapOptional("noVRegs", MF.NoVRegs); YamlIO.mapOptional("legalized", MF.Legalized); YamlIO.mapOptional("regBankSelected", MF.RegBankSelected); YamlIO.mapOptional("selected", MF.Selected); diff --git a/lib/CodeGen/MIRParser/MIRParser.cpp b/lib/CodeGen/MIRParser/MIRParser.cpp index 3dff1147631b..2e13d7730f27 100644 --- a/lib/CodeGen/MIRParser/MIRParser.cpp +++ b/lib/CodeGen/MIRParser/MIRParser.cpp @@ -330,6 +330,8 @@ bool MIRParserImpl::initializeMachineFunction(MachineFunction &MF) { MF.setAlignment(YamlMF.Alignment); MF.setExposesReturnsTwice(YamlMF.ExposesReturnsTwice); + if (YamlMF.NoVRegs) + MF.getProperties().set(MachineFunctionProperties::Property::NoVRegs); if (YamlMF.Legalized) MF.getProperties().set(MachineFunctionProperties::Property::Legalized); if (YamlMF.RegBankSelected) diff --git a/lib/CodeGen/MIRPrinter.cpp b/lib/CodeGen/MIRPrinter.cpp index db87092177ca..b3eeeaf1b8a4 100644 --- a/lib/CodeGen/MIRPrinter.cpp +++ b/lib/CodeGen/MIRPrinter.cpp @@ -175,6 +175,8 @@ void MIRPrinter::print(const MachineFunction &MF) { YamlMF.Alignment = MF.getAlignment(); YamlMF.ExposesReturnsTwice = MF.exposesReturnsTwice(); + YamlMF.NoVRegs = MF.getProperties().hasProperty( + MachineFunctionProperties::Property::NoVRegs); YamlMF.Legalized = MF.getProperties().hasProperty( MachineFunctionProperties::Property::Legalized); YamlMF.RegBankSelected = MF.getProperties().hasProperty( diff --git a/lib/Target/ARM/ARMConstantIslandPass.cpp b/lib/Target/ARM/ARMConstantIslandPass.cpp index e82d4f4db86f..45a881a76596 100644 --- a/lib/Target/ARM/ARMConstantIslandPass.cpp +++ b/lib/Target/ARM/ARMConstantIslandPass.cpp @@ -2033,7 +2033,7 @@ bool ARMConstantIslands::optimizeThumb2JumpTables() { unsigned DeadSize = 0; bool CanDeleteLEA = false; bool BaseRegKill = false; - + unsigned IdxReg = ~0U; bool IdxRegKill = true; if (isThumb2) { @@ -2061,6 +2061,12 @@ bool ARMConstantIslands::optimizeThumb2JumpTables() { IdxReg = Shift->getOperand(2).getReg(); unsigned ShiftedIdxReg = Shift->getOperand(0).getReg(); + // It's important that IdxReg is live until the actual TBB/TBH. Most of + // the range is checked later, but the LEA might still clobber it and not + // actually get removed. + if (BaseReg == IdxReg && !jumpTableFollowsTB(MI, User.CPEMI)) + continue; + MachineInstr *Load = User.MI->getNextNode(); if (Load->getOpcode() != ARM::tLDRr) continue; @@ -2086,15 +2092,15 @@ bool ARMConstantIslands::optimizeThumb2JumpTables() { if (Load->getOperand(0).getReg() != MI->getOperand(0).getReg()) continue; } - - + + // Now safe to delete the load and lsl. The LEA will be removed later. CanDeleteLEA = true; Shift->eraseFromParent(); Load->eraseFromParent(); DeadSize += 4; } - + DEBUG(dbgs() << "Shrink JT: " << *MI); MachineInstr *CPEMI = User.CPEMI; unsigned Opc = ByteOk ? ARM::t2TBB_JT : ARM::t2TBH_JT; diff --git a/test/CodeGen/ARM/v6-jumptable-clobber.mir b/test/CodeGen/ARM/v6-jumptable-clobber.mir new file mode 100644 index 000000000000..1346c4bbc552 --- /dev/null +++ b/test/CodeGen/ARM/v6-jumptable-clobber.mir @@ -0,0 +1,384 @@ +# RUN: llc -run-pass=arm-cp-islands -o - %s | FileCheck %s + +# Test created by tweaking the register allocation after stopping the IR below +# just before constant islands. We were forwarding the table index to the end of +# the block, even though the LEA clobbered it. + +# CHECK-LABEL: name: foo +# CHECK: tBR_JT + # This order is important. If the jump-table comes first then the + # transformation is valid because the LEA can be removed, see second test. +# CHECK: CONSTPOOL_ENTRY +# CHECK: JUMPTABLE_ADDRS + +# CHECK-LABEL: name: bar +# CHECK: tTBB_JT %pc, killed %r1 + +--- | + ; ModuleID = 'simple.ll' + source_filename = "simple.ll" + target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64" + target triple = "thumbv6m-none--eabi" + + define void @foo(i8 %in, i32* %addr) { + store i32 12345678, i32* %addr + %1 = call i32 @llvm.arm.space(i32 980, i32 undef) + %2 = zext i8 %in to i32 + switch i32 %2, label %default [ + i32 0, label %d1 + i32 1, label %d2 + i32 3, label %d3 + i32 4, label %d4 + i32 5, label %d5 + i32 6, label %d6 + i32 7, label %d7 + i32 2, label %d8 + i32 8, label %d9 + i32 9, label %d10 + i32 19, label %d11 + i32 20, label %d12 + i32 21, label %d13 + i32 22, label %d14 + i32 24, label %d15 + i32 25, label %d16 + i32 26, label %d17 + ] + + default: ; preds = %0 + unreachable + + d1: ; preds = %0 + unreachable + + d2: ; preds = %0 + unreachable + + d3: ; preds = %0 + unreachable + + d4: ; preds = %0 + unreachable + + d5: ; preds = %0 + unreachable + + d6: ; preds = %0 + unreachable + + d7: ; preds = %0 + unreachable + + d8: ; preds = %0 + unreachable + + d9: ; preds = %0 + unreachable + + d10: ; preds = %0 + unreachable + + d11: ; preds = %0 + unreachable + + d12: ; preds = %0 + unreachable + + d13: ; preds = %0 + unreachable + + d14: ; preds = %0 + unreachable + + d15: ; preds = %0 + unreachable + + d16: ; preds = %0 + unreachable + + d17: ; preds = %0 + unreachable + } + + define void @bar(i8 %in, i32* %addr) { + store i32 12345678, i32* %addr + %1 = zext i8 %in to i32 + switch i32 %1, label %default [ + i32 0, label %d1 + i32 1, label %d2 + i32 3, label %d3 + i32 4, label %d4 + i32 5, label %d5 + i32 6, label %d6 + i32 7, label %d7 + i32 2, label %d8 + i32 8, label %d9 + i32 9, label %d10 + i32 19, label %d11 + i32 20, label %d12 + i32 21, label %d13 + i32 22, label %d14 + i32 24, label %d15 + i32 25, label %d16 + i32 26, label %d17 + ] + + default: ; preds = %0 + unreachable + + d1: ; preds = %0 + unreachable + + d2: ; preds = %0 + unreachable + + d3: ; preds = %0 + unreachable + + d4: ; preds = %0 + unreachable + + d5: ; preds = %0 + unreachable + + d6: ; preds = %0 + unreachable + + d7: ; preds = %0 + unreachable + + d8: ; preds = %0 + unreachable + + d9: ; preds = %0 + unreachable + + d10: ; preds = %0 + unreachable + + d11: ; preds = %0 + unreachable + + d12: ; preds = %0 + unreachable + + d13: ; preds = %0 + unreachable + + d14: ; preds = %0 + unreachable + + d15: ; preds = %0 + unreachable + + d16: ; preds = %0 + unreachable + + d17: ; preds = %0 + unreachable + } + + ; Function Attrs: nounwind + declare i32 @llvm.arm.space(i32, i32) #0 + + ; Function Attrs: nounwind + declare void @llvm.stackprotector(i8*, i8**) #0 + + attributes #0 = { nounwind } + +... +--- +name: foo +alignment: 1 +exposesReturnsTwice: false +noVRegs: true +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +liveins: + - { reg: '%r0' } + - { reg: '%r1' } +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 +constants: + - id: 0 + value: i32 12345678 + alignment: 4 +jumpTable: + kind: inline + entries: + - id: 0 + blocks: [ '%bb.3.d2', '%bb.9.d8', '%bb.4.d3', '%bb.5.d4', + '%bb.6.d5', '%bb.7.d6', '%bb.8.d7', '%bb.10.d9', + '%bb.11.d10', '%bb.2.d1', '%bb.2.d1', '%bb.2.d1', + '%bb.2.d1', '%bb.2.d1', '%bb.2.d1', '%bb.2.d1', + '%bb.2.d1', '%bb.2.d1', '%bb.12.d11', '%bb.13.d12', + '%bb.14.d13', '%bb.15.d14', '%bb.2.d1', '%bb.16.d15', + '%bb.17.d16', '%bb.18.d17' ] +body: | + bb.0 (%ir-block.0): + successors: %bb.2.d1(0x03c3c3c4), %bb.1(0x7c3c3c3c) + liveins: %r0, %r1 + + %r2 = tLDRpci %const.0, 14, _ + tSTRi killed %r2, killed %r1, 0, 14, _ :: (store 4 into %ir.addr) + dead %r1 = SPACE 980, undef %r0 + %r0 = tUXTB killed %r0, 14, _ + %r1, dead %cpsr = tSUBi3 killed %r0, 1, 14, _ + tCMPi8 %r1, 25, 14, _, implicit-def %cpsr + tBcc %bb.2.d1, 8, killed %cpsr + + bb.1 (%ir-block.0): + successors: %bb.3.d2(0x07c549d2), %bb.9.d8(0x07c549d2), %bb.4.d3(0x07c549d2), %bb.5.d4(0x07c549d2), %bb.6.d5(0x07c549d2), %bb.7.d6(0x07c549d2), %bb.8.d7(0x07c549d2), %bb.10.d9(0x07c549d2), %bb.11.d10(0x07c549d2), %bb.2.d1(0x03ab62db), %bb.12.d11(0x07c549d2), %bb.13.d12(0x07c549d2), %bb.14.d13(0x07c549d2), %bb.15.d14(0x07c549d2), %bb.16.d15(0x07c549d2), %bb.17.d16(0x07c549d2), %bb.18.d17(0x07c549d2) + liveins: %r1 + + %r0, dead %cpsr = tLSLri killed %r1, 2, 14, _ + %r1 = tLEApcrelJT %jump-table.0, 14, _ + %r0 = tLDRr killed %r0, killed %r1, 14, _ :: (load 4 from jump-table) + tBR_JTr killed %r0, %jump-table.0 + + bb.3.d2: + + bb.9.d8: + + bb.4.d3: + + bb.5.d4: + + bb.6.d5: + + bb.7.d6: + + bb.8.d7: + + bb.10.d9: + + bb.11.d10: + + bb.2.d1: + + bb.12.d11: + + bb.13.d12: + + bb.14.d13: + + bb.15.d14: + + bb.16.d15: + + bb.17.d16: + + bb.18.d17: + +... + +--- +name: bar +alignment: 1 +exposesReturnsTwice: false +noVRegs: true +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +liveins: + - { reg: '%r0' } + - { reg: '%r1' } +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 +constants: + - id: 0 + value: i32 12345678 + alignment: 4 +jumpTable: + kind: inline + entries: + - id: 0 + blocks: [ '%bb.3.d2', '%bb.9.d8', '%bb.4.d3', '%bb.5.d4', + '%bb.6.d5', '%bb.7.d6', '%bb.8.d7', '%bb.10.d9', + '%bb.11.d10', '%bb.2.d1', '%bb.2.d1', '%bb.2.d1', + '%bb.2.d1', '%bb.2.d1', '%bb.2.d1', '%bb.2.d1', + '%bb.2.d1', '%bb.2.d1', '%bb.12.d11', '%bb.13.d12', + '%bb.14.d13', '%bb.15.d14', '%bb.2.d1', '%bb.16.d15', + '%bb.17.d16', '%bb.18.d17' ] +body: | + bb.0 (%ir-block.0): + successors: %bb.2.d1(0x03c3c3c4), %bb.1(0x7c3c3c3c) + liveins: %r0, %r1 + + %r2 = tLDRpci %const.0, 14, _ + tSTRi killed %r2, killed %r1, 0, 14, _ :: (store 4 into %ir.addr) + %r0 = tUXTB killed %r0, 14, _ + %r1, dead %cpsr = tSUBi3 killed %r0, 1, 14, _ + tCMPi8 %r1, 25, 14, _, implicit-def %cpsr + tBcc %bb.2.d1, 8, killed %cpsr + + bb.1 (%ir-block.0): + successors: %bb.3.d2(0x07c549d2), %bb.9.d8(0x07c549d2), %bb.4.d3(0x07c549d2), %bb.5.d4(0x07c549d2), %bb.6.d5(0x07c549d2), %bb.7.d6(0x07c549d2), %bb.8.d7(0x07c549d2), %bb.10.d9(0x07c549d2), %bb.11.d10(0x07c549d2), %bb.2.d1(0x03ab62db), %bb.12.d11(0x07c549d2), %bb.13.d12(0x07c549d2), %bb.14.d13(0x07c549d2), %bb.15.d14(0x07c549d2), %bb.16.d15(0x07c549d2), %bb.17.d16(0x07c549d2), %bb.18.d17(0x07c549d2) + liveins: %r1 + + %r0, dead %cpsr = tLSLri killed %r1, 2, 14, _ + %r1 = tLEApcrelJT %jump-table.0, 14, _ + %r0 = tLDRr killed %r0, killed %r1, 14, _ :: (load 4 from jump-table) + tBR_JTr killed %r0, %jump-table.0 + + bb.3.d2: + + bb.9.d8: + + bb.4.d3: + + bb.5.d4: + + bb.6.d5: + + bb.7.d6: + + bb.8.d7: + + bb.10.d9: + + bb.11.d10: + + bb.2.d1: + + bb.12.d11: + + bb.13.d12: + + bb.14.d13: + + bb.15.d14: + + bb.16.d15: + + bb.17.d16: + + bb.18.d17: + +... diff --git a/test/CodeGen/X86/GlobalISel/irtranslator-call.ll b/test/CodeGen/X86/GlobalISel/irtranslator-call.ll index 425d2609380e..c1bf44417666 100644 --- a/test/CodeGen/X86/GlobalISel/irtranslator-call.ll +++ b/test/CodeGen/X86/GlobalISel/irtranslator-call.ll @@ -5,6 +5,7 @@ define void @test_void_return() { ; CHECK-LABEL: name: test_void_return ; CHECK: alignment: 4 ; CHECK-NEXT: exposesReturnsTwice: false +; CHECK-NEXT: noVRegs: false ; CHECK-NEXT: legalized: false ; CHECK-NEXT: regBankSelected: false ; CHECK-NEXT: selected: false From 7c5864626d044313a29bd9e579389caa3b3de2c3 Mon Sep 17 00:00:00 2001 From: James Molloy Date: Mon, 13 Feb 2017 14:07:39 +0000 Subject: [PATCH 2/5] TBB generation: spot redefinitions of index register We match a sequence of 3-4 instructions into a tTBB pseudo. One of our checks is that a particular register in that sequence is killed (so it can be clobbered by the pseudo). We weren't noticing if an errant MOV or other instruction had infiltrated the sequence we were walking. If it had, and it defined the register we've already identified as killed, it makes it live across the tBR_JT and thus unclobberable. Notice this case and bail out. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@294949 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMConstantIslandPass.cpp | 18 ++- test/CodeGen/Thumb/tbb-reuse.mir | 151 +++++++++++++++++++++++ 2 files changed, 168 insertions(+), 1 deletion(-) create mode 100644 test/CodeGen/Thumb/tbb-reuse.mir diff --git a/lib/Target/ARM/ARMConstantIslandPass.cpp b/lib/Target/ARM/ARMConstantIslandPass.cpp index 45a881a76596..32a41830897e 100644 --- a/lib/Target/ARM/ARMConstantIslandPass.cpp +++ b/lib/Target/ARM/ARMConstantIslandPass.cpp @@ -1984,6 +1984,16 @@ static bool jumpTableFollowsTB(MachineInstr *JTMI, MachineInstr *CPEMI) { &*MBB->begin() == CPEMI; } +static bool registerDefinedBetween(unsigned Reg, + MachineBasicBlock::iterator From, + MachineBasicBlock::iterator To, + const TargetRegisterInfo *TRI) { + for (auto I = From; I != To; ++I) + if (I->modifiesRegister(Reg, TRI)) + return true; + return false; +} + /// optimizeThumb2JumpTables - Use tbb / tbh instructions to generate smaller /// jumptables when it's possible. bool ARMConstantIslands::optimizeThumb2JumpTables() { @@ -2076,6 +2086,7 @@ bool ARMConstantIslands::optimizeThumb2JumpTables() { continue; // If we're in PIC mode, there should be another ADD following. + auto *TRI = STI->getRegisterInfo(); if (isPositionIndependentOrROPI) { MachineInstr *Add = Load->getNextNode(); if (Add->getOpcode() != ARM::tADDrr || @@ -2085,12 +2096,17 @@ bool ARMConstantIslands::optimizeThumb2JumpTables() { continue; if (Add->getOperand(0).getReg() != MI->getOperand(0).getReg()) continue; - + if (registerDefinedBetween(IdxReg, Add->getNextNode(), MI, TRI)) + // IdxReg gets redefined in the middle of the sequence. + continue; Add->eraseFromParent(); DeadSize += 2; } else { if (Load->getOperand(0).getReg() != MI->getOperand(0).getReg()) continue; + if (registerDefinedBetween(IdxReg, Load->getNextNode(), MI, TRI)) + // IdxReg gets redefined in the middle of the sequence. + continue; } diff --git a/test/CodeGen/Thumb/tbb-reuse.mir b/test/CodeGen/Thumb/tbb-reuse.mir new file mode 100644 index 000000000000..15b9fa184c38 --- /dev/null +++ b/test/CodeGen/Thumb/tbb-reuse.mir @@ -0,0 +1,151 @@ +# RUN: llc -run-pass arm-cp-islands %s -o - | FileCheck %s + +--- | + ; ModuleID = '' + source_filename = "" + target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64" + target triple = "thumbv6m--none-eabi" + + declare void @exit0() + + declare void @exit1(i32) + + declare void @exit2() + + declare void @exit3() + + declare void @exit4() + + define void @jump_table(i32 %val, i32 %arg2, i32 %arg3, i32 %arg4) { + entry: + switch i32 %val, label %default [ + i32 1, label %lab1 + i32 2, label %lab2 + i32 3, label %lab3 + i32 4, label %lab4 + ] + + default: ; preds = %entry + tail call void @exit0() + ret void + + lab1: ; preds = %entry + %b = sub i32 %val, 1 + %a = shl i32 %b, 2 + tail call void @exit1(i32 %a) + ret void + + lab2: ; preds = %entry + tail call void @exit2() + ret void + + lab3: ; preds = %entry + tail call void @exit3() + ret void + + lab4: ; preds = %entry + tail call void @exit4() + ret void + } + + ; Function Attrs: nounwind + declare void @llvm.stackprotector(i8*, i8**) #0 + + attributes #0 = { nounwind } + +... +--- +name: jump_table +alignment: 1 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +liveins: + - { reg: '%r0' } +calleeSavedRegisters: [ '%lr', '%d8', '%d9', '%d10', '%d11', '%d12', '%d13', + '%d14', '%d15', '%q4', '%q5', '%q6', '%q7', '%r4', + '%r5', '%r6', '%r7', '%r8', '%r9', '%r10', '%r11', + '%s16', '%s17', '%s18', '%s19', '%s20', '%s21', + '%s22', '%s23', '%s24', '%s25', '%s26', '%s27', + '%s28', '%s29', '%s30', '%s31', '%d8_d10', '%d9_d11', + '%d10_d12', '%d11_d13', '%d12_d14', '%d13_d15', + '%q4_q5', '%q5_q6', '%q6_q7', '%q4_q5_q6_q7', '%r4_r5', + '%r6_r7', '%r8_r9', '%r10_r11', '%d8_d9_d10', '%d9_d10_d11', + '%d10_d11_d12', '%d11_d12_d13', '%d12_d13_d14', + '%d13_d14_d15', '%d8_d10_d12', '%d9_d11_d13', '%d10_d12_d14', + '%d11_d13_d15', '%d8_d10_d12_d14', '%d9_d11_d13_d15', + '%d9_d10', '%d11_d12', '%d13_d14', '%d9_d10_d11_d12', + '%d11_d12_d13_d14' ] +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 8 + offsetAdjustment: 0 + maxAlignment: 4 + adjustsStack: true + hasCalls: true + maxCallFrameSize: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false +stack: + - { id: 0, type: spill-slot, offset: -4, size: 4, alignment: 4, callee-saved-register: '%lr' } + - { id: 1, type: spill-slot, offset: -8, size: 4, alignment: 4, callee-saved-register: '%r7' } +jumpTable: + kind: inline + entries: + - id: 0 + blocks: [ '%bb.3.lab1', '%bb.4.lab2', '%bb.5.lab3', '%bb.6.lab4' ] +# r1 is redefined in the middle of the recognizable jump sequence - it shouldn't be clobbered! +# CHECK-NOT: tTBB_JT + +body: | + bb.0.entry: + successors: %bb.2.default(0x19999998), %bb.1.entry(0x66666668) + liveins: %r0, %r7, %lr + + frame-setup tPUSH 14, _, killed %r7, killed %lr, implicit-def %sp, implicit %sp + frame-setup CFI_INSTRUCTION def_cfa_offset 8 + frame-setup CFI_INSTRUCTION offset %lr, -4 + frame-setup CFI_INSTRUCTION offset %r7, -8 + %r1, dead %cpsr = tSUBi3 %r0, 1, 14, _ + tCMPi8 %r1, 3, 14, _, implicit-def %cpsr + tBcc %bb.2.default, 8, killed %cpsr + + bb.1.entry: + successors: %bb.3.lab1(0x20000000), %bb.4.lab2(0x20000000), %bb.5.lab3(0x20000000), %bb.6.lab4(0x20000000) + liveins: %r0, %r1 + + %r1, dead %cpsr = tLSLri killed %r1, 2, 14, _ + %r2 = tLEApcrelJT %jump-table.0, 14, _ + %r2 = tLDRr killed %r1, killed %r2, 14, _ :: (load 4 from jump-table) + %r1, dead %cpsr = tLSLri %r2, 2, 14, _ + tBR_JTr killed %r2, %jump-table.0 + + bb.2.default: + tBL 14, _, @exit0, csr_aapcs, implicit-def dead %lr, implicit %sp, implicit-def %sp + tPOP_RET 14, _, def %r7, def %pc, implicit-def %sp, implicit %sp + + bb.3.lab1: + liveins: %r0,%r1 + + tBL 14, _, @exit1, csr_aapcs, implicit-def dead %lr, implicit %sp, implicit %r0, implicit-def %sp + tPOP_RET 14, _, def %r7, def %pc, implicit-def %sp, implicit %sp + + bb.4.lab2: + tBL 14, _, @exit2, csr_aapcs, implicit-def dead %lr, implicit %sp, implicit-def %sp + tPOP_RET 14, _, def %r7, def %pc, implicit-def %sp, implicit %sp + + bb.5.lab3: + tBL 14, _, @exit3, csr_aapcs, implicit-def dead %lr, implicit %sp, implicit-def %sp + tPOP_RET 14, _, def %r7, def %pc, implicit-def %sp, implicit %sp + + bb.6.lab4: + tBL 14, _, @exit4, csr_aapcs, implicit-def dead %lr, implicit %sp, implicit-def %sp + tPOP_RET 14, _, def %r7, def %pc, implicit-def %sp, implicit %sp + +... From 96583da997794cbe981319208dc585c9286a2d4e Mon Sep 17 00:00:00 2001 From: Roger Ferrer Ibanez Date: Wed, 22 Feb 2017 09:06:21 +0000 Subject: [PATCH 3/5] Fix constant islands pass. The pass tries to fix a spill of LR that turns out to be unnecessary. So it removes the tPOP but forgets to remove tPUSH. This causes the stack be misaligned upon returning the function. Thus, remove the tPUSH as well in this case. Differential Revision: https://reviews.llvm.org/D30207 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@295816 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMConstantIslandPass.cpp | 7 + .../CodeGen/Thumb/remove-unneeded-push-pop.ll | 1052 +++++++++++++++++ 2 files changed, 1059 insertions(+) create mode 100644 test/CodeGen/Thumb/remove-unneeded-push-pop.ll diff --git a/lib/Target/ARM/ARMConstantIslandPass.cpp b/lib/Target/ARM/ARMConstantIslandPass.cpp index 32a41830897e..76df13d6bcd0 100644 --- a/lib/Target/ARM/ARMConstantIslandPass.cpp +++ b/lib/Target/ARM/ARMConstantIslandPass.cpp @@ -1715,6 +1715,13 @@ bool ARMConstantIslands::undoLRSpillRestore() { MI->eraseFromParent(); MadeChange = true; } + if (MI->getOpcode() == ARM::tPUSH && + MI->getOperand(2).getReg() == ARM::LR && + MI->getNumExplicitOperands() == 3) { + // Just remove the push. + MI->eraseFromParent(); + MadeChange = true; + } } return MadeChange; } diff --git a/test/CodeGen/Thumb/remove-unneeded-push-pop.ll b/test/CodeGen/Thumb/remove-unneeded-push-pop.ll new file mode 100644 index 000000000000..054be2ea8587 --- /dev/null +++ b/test/CodeGen/Thumb/remove-unneeded-push-pop.ll @@ -0,0 +1,1052 @@ +; RUN: llc -O0 -mtriple thumbv6m-arm-none-eabi < %s | FileCheck %s + +@a = external hidden global i32*, align 4 +@f = external hidden global i32, align 4 + +define hidden void @foo() { +entry: +; CHECK-NOT: push {lr} +; CHECK-NOT: pop {pc} + store i32 24654, i32* @f, align 4 + br label %if.end + +if.end: ; preds = %entry + %0 = load i32*, i32** @a, align 4 + %arrayidx1 = getelementptr inbounds i32, i32* %0, i32 2 + %1 = load i32, i32* %arrayidx1, align 4 + %tobool2 = icmp ne i32 %1, 0 + br i1 %tobool2, label %if.then3, label %if.end4 + +if.then3: ; preds = %if.end + store i32 17785, i32* @f, align 4 + br label %if.end4 + +if.end4: ; preds = %if.then3, %if.end + %2 = load i32*, i32** @a, align 4 + %arrayidx5 = getelementptr inbounds i32, i32* %2, i32 3 + %3 = load i32, i32* %arrayidx5, align 4 + %tobool6 = icmp ne i32 %3, 0 + br i1 %tobool6, label %if.then7, label %if.end8 + +if.then7: ; preds = %if.end4 + store i32 10342, i32* @f, align 4 + br label %if.end8 + +if.end8: ; preds = %if.then7, %if.end4 + %4 = load i32*, i32** @a, align 4 + %arrayidx9 = getelementptr inbounds i32, i32* %4, i32 4 + %5 = load i32, i32* %arrayidx9, align 4 + %tobool10 = icmp ne i32 %5, 0 + br i1 %tobool10, label %if.then11, label %if.end12 + +if.then11: ; preds = %if.end8 + store i32 29082, i32* @f, align 4 + br label %if.end12 + +if.end12: ; preds = %if.then11, %if.end8 + %6 = load i32*, i32** @a, align 4 + %arrayidx13 = getelementptr inbounds i32, i32* %6, i32 5 + %7 = load i32, i32* %arrayidx13, align 4 + %tobool14 = icmp ne i32 %7, 0 + br i1 %tobool14, label %if.then15, label %if.end16 + +if.then15: ; preds = %if.end12 + store i32 29893, i32* @f, align 4 + br label %if.end16 + +if.end16: ; preds = %if.then15, %if.end12 + %8 = load i32*, i32** @a, align 4 + %arrayidx17 = getelementptr inbounds i32, i32* %8, i32 6 + %9 = load i32, i32* %arrayidx17, align 4 + %tobool18 = icmp ne i32 %9, 0 + br i1 %tobool18, label %if.then19, label %if.end20 + +if.then19: ; preds = %if.end16 + store i32 19071, i32* @f, align 4 + br label %if.end20 + +if.end20: ; preds = %if.then19, %if.end16 + %10 = load i32*, i32** @a, align 4 + %arrayidx21 = getelementptr inbounds i32, i32* %10, i32 7 + %11 = load i32, i32* %arrayidx21, align 4 + %tobool22 = icmp ne i32 %11, 0 + br i1 %tobool22, label %if.then23, label %if.end24 + +if.then23: ; preds = %if.end20 + store i32 6154, i32* @f, align 4 + br label %if.end24 + +if.end24: ; preds = %if.then23, %if.end20 + %12 = load i32*, i32** @a, align 4 + %arrayidx25 = getelementptr inbounds i32, i32* %12, i32 8 + %13 = load i32, i32* %arrayidx25, align 4 + %tobool26 = icmp ne i32 %13, 0 + br i1 %tobool26, label %if.then27, label %if.end28 + +if.then27: ; preds = %if.end24 + store i32 30498, i32* @f, align 4 + br label %if.end28 + +if.end28: ; preds = %if.then27, %if.end24 + %14 = load i32*, i32** @a, align 4 + %arrayidx29 = getelementptr inbounds i32, i32* %14, i32 9 + %15 = load i32, i32* %arrayidx29, align 4 + %tobool30 = icmp ne i32 %15, 0 + br i1 %tobool30, label %if.then31, label %if.end32 + +if.then31: ; preds = %if.end28 + store i32 16667, i32* @f, align 4 + br label %if.end32 + +if.end32: ; preds = %if.then31, %if.end28 + %16 = load i32*, i32** @a, align 4 + %arrayidx33 = getelementptr inbounds i32, i32* %16, i32 10 + %17 = load i32, i32* %arrayidx33, align 4 + %tobool34 = icmp ne i32 %17, 0 + br i1 %tobool34, label %if.then35, label %if.end36 + +if.then35: ; preds = %if.end32 + store i32 195, i32* @f, align 4 + br label %if.end36 + +if.end36: ; preds = %if.then35, %if.end32 + %18 = load i32*, i32** @a, align 4 + %arrayidx37 = getelementptr inbounds i32, i32* %18, i32 11 + %19 = load i32, i32* %arrayidx37, align 4 + %tobool38 = icmp ne i32 %19, 0 + br i1 %tobool38, label %if.then39, label %if.end40 + +if.then39: ; preds = %if.end36 + store i32 14665, i32* @f, align 4 + br label %if.end40 + +if.end40: ; preds = %if.then39, %if.end36 + %20 = load i32*, i32** @a, align 4 + %arrayidx41 = getelementptr inbounds i32, i32* %20, i32 12 + %21 = load i32, i32* %arrayidx41, align 4 + %tobool42 = icmp ne i32 %21, 0 + br i1 %tobool42, label %if.then43, label %if.end44 + +if.then43: ; preds = %if.end40 + store i32 19305, i32* @f, align 4 + br label %if.end44 + +if.end44: ; preds = %if.then43, %if.end40 + %22 = load i32*, i32** @a, align 4 + %arrayidx45 = getelementptr inbounds i32, i32* %22, i32 13 + %23 = load i32, i32* %arrayidx45, align 4 + %tobool46 = icmp ne i32 %23, 0 + br i1 %tobool46, label %if.then47, label %if.end48 + +if.then47: ; preds = %if.end44 + store i32 15133, i32* @f, align 4 + br label %if.end48 + +if.end48: ; preds = %if.then47, %if.end44 + %24 = load i32*, i32** @a, align 4 + %arrayidx49 = getelementptr inbounds i32, i32* %24, i32 14 + %25 = load i32, i32* %arrayidx49, align 4 + %tobool50 = icmp ne i32 %25, 0 + br i1 %tobool50, label %if.then51, label %if.end52 + +if.then51: ; preds = %if.end48 + store i32 19173, i32* @f, align 4 + br label %if.end52 + +if.end52: ; preds = %if.then51, %if.end48 + br label %if.then55 + +if.then55: ; preds = %if.end52 + store i32 14025, i32* @f, align 4 + br label %if.end56 + +if.end56: ; preds = %if.then55 + %26 = load i32*, i32** @a, align 4 + %arrayidx57 = getelementptr inbounds i32, i32* %26, i32 16 + %27 = load i32, i32* %arrayidx57, align 4 + %tobool58 = icmp ne i32 %27, 0 + br i1 %tobool58, label %if.then59, label %if.end60 + +if.then59: ; preds = %if.end56 + store i32 8209, i32* @f, align 4 + br label %if.end60 + +if.end60: ; preds = %if.then59, %if.end56 + %28 = load i32*, i32** @a, align 4 + %arrayidx61 = getelementptr inbounds i32, i32* %28, i32 17 + %29 = load i32, i32* %arrayidx61, align 4 + %tobool62 = icmp ne i32 %29, 0 + br i1 %tobool62, label %if.then63, label %if.end64 + +if.then63: ; preds = %if.end60 + store i32 29621, i32* @f, align 4 + br label %if.end64 + +if.end64: ; preds = %if.then63, %if.end60 + %30 = load i32*, i32** @a, align 4 + %arrayidx65 = getelementptr inbounds i32, i32* %30, i32 18 + %31 = load i32, i32* %arrayidx65, align 4 + %tobool66 = icmp ne i32 %31, 0 + br i1 %tobool66, label %if.then67, label %if.end68 + +if.then67: ; preds = %if.end64 + store i32 14963, i32* @f, align 4 + br label %if.end68 + +if.end68: ; preds = %if.then67, %if.end64 + %32 = load i32*, i32** @a, align 4 + %arrayidx69 = getelementptr inbounds i32, i32* %32, i32 19 + %33 = load i32, i32* %arrayidx69, align 4 + %tobool70 = icmp ne i32 %33, 0 + br i1 %tobool70, label %if.then71, label %if.end72 + +if.then71: ; preds = %if.end68 + store i32 32282, i32* @f, align 4 + br label %if.end72 + +if.end72: ; preds = %if.then71, %if.end68 + %34 = load i32*, i32** @a, align 4 + %arrayidx73 = getelementptr inbounds i32, i32* %34, i32 20 + %35 = load i32, i32* %arrayidx73, align 4 + %tobool74 = icmp ne i32 %35, 0 + br i1 %tobool74, label %if.then75, label %if.end76 + +if.then75: ; preds = %if.end72 + store i32 3072, i32* @f, align 4 + br label %if.end76 + +if.end76: ; preds = %if.then75, %if.end72 + %36 = load i32*, i32** @a, align 4 + %arrayidx77 = getelementptr inbounds i32, i32* %36, i32 21 + %37 = load i32, i32* %arrayidx77, align 4 + %tobool78 = icmp ne i32 %37, 0 + br i1 %tobool78, label %if.then79, label %if.end80 + +if.then79: ; preds = %if.end76 + store i32 1992, i32* @f, align 4 + br label %if.end80 + +if.end80: ; preds = %if.then79, %if.end76 + %38 = load i32*, i32** @a, align 4 + %arrayidx81 = getelementptr inbounds i32, i32* %38, i32 22 + %39 = load i32, i32* %arrayidx81, align 4 + %tobool82 = icmp ne i32 %39, 0 + br i1 %tobool82, label %if.then83, label %if.end84 + +if.then83: ; preds = %if.end80 + store i32 9614, i32* @f, align 4 + br label %if.end84 + +if.end84: ; preds = %if.then83, %if.end80 + %40 = load i32*, i32** @a, align 4 + %arrayidx85 = getelementptr inbounds i32, i32* %40, i32 23 + %41 = load i32, i32* %arrayidx85, align 4 + %tobool86 = icmp ne i32 %41, 0 + br i1 %tobool86, label %if.then87, label %if.end88 + +if.then87: ; preds = %if.end84 + store i32 25931, i32* @f, align 4 + br label %if.end88 + +if.end88: ; preds = %if.then87, %if.end84 + %42 = load i32*, i32** @a, align 4 + %arrayidx89 = getelementptr inbounds i32, i32* %42, i32 24 + %43 = load i32, i32* %arrayidx89, align 4 + %tobool90 = icmp ne i32 %43, 0 + br i1 %tobool90, label %if.then91, label %if.end92 + +if.then91: ; preds = %if.end88 + store i32 22035, i32* @f, align 4 + br label %if.end92 + +if.end92: ; preds = %if.then91, %if.end88 + %44 = load i32*, i32** @a, align 4 + %arrayidx93 = getelementptr inbounds i32, i32* %44, i32 25 + %45 = load i32, i32* %arrayidx93, align 4 + %tobool94 = icmp ne i32 %45, 0 + br i1 %tobool94, label %if.then95, label %if.end96 + +if.then95: ; preds = %if.end92 + store i32 10712, i32* @f, align 4 + br label %if.end96 + +if.end96: ; preds = %if.then95, %if.end92 + %46 = load i32*, i32** @a, align 4 + %arrayidx97 = getelementptr inbounds i32, i32* %46, i32 26 + %47 = load i32, i32* %arrayidx97, align 4 + %tobool98 = icmp ne i32 %47, 0 + br i1 %tobool98, label %if.then99, label %if.end100 + +if.then99: ; preds = %if.end96 + store i32 18267, i32* @f, align 4 + br label %if.end100 + +if.end100: ; preds = %if.then99, %if.end96 + %48 = load i32*, i32** @a, align 4 + %arrayidx101 = getelementptr inbounds i32, i32* %48, i32 27 + %49 = load i32, i32* %arrayidx101, align 4 + %tobool102 = icmp ne i32 %49, 0 + br i1 %tobool102, label %if.then103, label %if.end104 + +if.then103: ; preds = %if.end100 + store i32 30432, i32* @f, align 4 + br label %if.end104 + +if.end104: ; preds = %if.then103, %if.end100 + %50 = load i32*, i32** @a, align 4 + %arrayidx105 = getelementptr inbounds i32, i32* %50, i32 28 + %51 = load i32, i32* %arrayidx105, align 4 + %tobool106 = icmp ne i32 %51, 0 + br i1 %tobool106, label %if.then107, label %if.end108 + +if.then107: ; preds = %if.end104 + store i32 5847, i32* @f, align 4 + br label %if.end108 + +if.end108: ; preds = %if.then107, %if.end104 + %52 = load i32*, i32** @a, align 4 + %arrayidx109 = getelementptr inbounds i32, i32* %52, i32 29 + %53 = load i32, i32* %arrayidx109, align 4 + %tobool110 = icmp ne i32 %53, 0 + br i1 %tobool110, label %if.then111, label %if.end112 + +if.then111: ; preds = %if.end108 + store i32 14705, i32* @f, align 4 + br label %if.end112 + +if.end112: ; preds = %if.then111, %if.end108 + %54 = load i32*, i32** @a, align 4 + %arrayidx113 = getelementptr inbounds i32, i32* %54, i32 30 + %55 = load i32, i32* %arrayidx113, align 4 + %tobool114 = icmp ne i32 %55, 0 + br i1 %tobool114, label %if.then115, label %if.end116 + +if.then115: ; preds = %if.end112 + store i32 28488, i32* @f, align 4 + br label %if.end116 + +if.end116: ; preds = %if.then115, %if.end112 + %56 = load i32*, i32** @a, align 4 + %arrayidx117 = getelementptr inbounds i32, i32* %56, i32 31 + %57 = load i32, i32* %arrayidx117, align 4 + %tobool118 = icmp ne i32 %57, 0 + br i1 %tobool118, label %if.then119, label %if.end120 + +if.then119: ; preds = %if.end116 + store i32 13853, i32* @f, align 4 + br label %if.end120 + +if.end120: ; preds = %if.then119, %if.end116 + %58 = load i32*, i32** @a, align 4 + %arrayidx121 = getelementptr inbounds i32, i32* %58, i32 32 + %59 = load i32, i32* %arrayidx121, align 4 + %tobool122 = icmp ne i32 %59, 0 + br i1 %tobool122, label %if.then123, label %if.end124 + +if.then123: ; preds = %if.end120 + store i32 31379, i32* @f, align 4 + br label %if.end124 + +if.end124: ; preds = %if.then123, %if.end120 + %60 = load i32*, i32** @a, align 4 + %arrayidx125 = getelementptr inbounds i32, i32* %60, i32 33 + %61 = load i32, i32* %arrayidx125, align 4 + %tobool126 = icmp ne i32 %61, 0 + br i1 %tobool126, label %if.then127, label %if.end128 + +if.then127: ; preds = %if.end124 + store i32 7010, i32* @f, align 4 + br label %if.end128 + +if.end128: ; preds = %if.then127, %if.end124 + br label %if.then131 + +if.then131: ; preds = %if.end128 + store i32 31840, i32* @f, align 4 + br label %if.end132 + +if.end132: ; preds = %if.then131 + %62 = load i32*, i32** @a, align 4 + %arrayidx133 = getelementptr inbounds i32, i32* %62, i32 35 + %63 = load i32, i32* %arrayidx133, align 4 + %tobool134 = icmp ne i32 %63, 0 + br i1 %tobool134, label %if.then135, label %if.end136 + +if.then135: ; preds = %if.end132 + store i32 16119, i32* @f, align 4 + br label %if.end136 + +if.end136: ; preds = %if.then135, %if.end132 + %64 = load i32*, i32** @a, align 4 + %arrayidx137 = getelementptr inbounds i32, i32* %64, i32 36 + %65 = load i32, i32* %arrayidx137, align 4 + %tobool138 = icmp ne i32 %65, 0 + br i1 %tobool138, label %if.then139, label %if.end140 + +if.then139: ; preds = %if.end136 + store i32 7119, i32* @f, align 4 + br label %if.end140 + +if.end140: ; preds = %if.then139, %if.end136 + %66 = load i32*, i32** @a, align 4 + %arrayidx141 = getelementptr inbounds i32, i32* %66, i32 37 + %67 = load i32, i32* %arrayidx141, align 4 + %tobool142 = icmp ne i32 %67, 0 + br i1 %tobool142, label %if.then143, label %if.end144 + +if.then143: ; preds = %if.end140 + store i32 3333, i32* @f, align 4 + br label %if.end144 + +if.end144: ; preds = %if.then143, %if.end140 + %68 = load i32*, i32** @a, align 4 + %arrayidx145 = getelementptr inbounds i32, i32* %68, i32 38 + %69 = load i32, i32* %arrayidx145, align 4 + %tobool146 = icmp ne i32 %69, 0 + br i1 %tobool146, label %if.then147, label %if.end148 + +if.then147: ; preds = %if.end144 + store i32 6430, i32* @f, align 4 + br label %if.end148 + +if.end148: ; preds = %if.then147, %if.end144 + %70 = load i32*, i32** @a, align 4 + %arrayidx149 = getelementptr inbounds i32, i32* %70, i32 39 + %71 = load i32, i32* %arrayidx149, align 4 + %tobool150 = icmp ne i32 %71, 0 + br i1 %tobool150, label %if.then151, label %if.end152 + +if.then151: ; preds = %if.end148 + store i32 19857, i32* @f, align 4 + br label %if.end152 + +if.end152: ; preds = %if.then151, %if.end148 + %72 = load i32*, i32** @a, align 4 + %arrayidx153 = getelementptr inbounds i32, i32* %72, i32 40 + %73 = load i32, i32* %arrayidx153, align 4 + %tobool154 = icmp ne i32 %73, 0 + br i1 %tobool154, label %if.then155, label %if.end156 + +if.then155: ; preds = %if.end152 + store i32 13237, i32* @f, align 4 + br label %if.end156 + +if.end156: ; preds = %if.then155, %if.end152 + br label %if.then159 + +if.then159: ; preds = %if.end156 + store i32 163, i32* @f, align 4 + br label %if.end160 + +if.end160: ; preds = %if.then159 + %74 = load i32*, i32** @a, align 4 + %arrayidx161 = getelementptr inbounds i32, i32* %74, i32 42 + %75 = load i32, i32* %arrayidx161, align 4 + %tobool162 = icmp ne i32 %75, 0 + br i1 %tobool162, label %if.then163, label %if.end164 + +if.then163: ; preds = %if.end160 + store i32 1961, i32* @f, align 4 + br label %if.end164 + +if.end164: ; preds = %if.then163, %if.end160 + %76 = load i32*, i32** @a, align 4 + %arrayidx165 = getelementptr inbounds i32, i32* %76, i32 43 + %77 = load i32, i32* %arrayidx165, align 4 + %tobool166 = icmp ne i32 %77, 0 + br i1 %tobool166, label %if.then167, label %if.end168 + +if.then167: ; preds = %if.end164 + store i32 11325, i32* @f, align 4 + br label %if.end168 + +if.end168: ; preds = %if.then167, %if.end164 + %78 = load i32*, i32** @a, align 4 + %arrayidx169 = getelementptr inbounds i32, i32* %78, i32 44 + %79 = load i32, i32* %arrayidx169, align 4 + %tobool170 = icmp ne i32 %79, 0 + br i1 %tobool170, label %if.then171, label %if.end172 + +if.then171: ; preds = %if.end168 + store i32 12189, i32* @f, align 4 + br label %if.end172 + +if.end172: ; preds = %if.then171, %if.end168 + %80 = load i32*, i32** @a, align 4 + %arrayidx173 = getelementptr inbounds i32, i32* %80, i32 45 + %81 = load i32, i32* %arrayidx173, align 4 + %tobool174 = icmp ne i32 %81, 0 + br i1 %tobool174, label %if.then175, label %if.end176 + +if.then175: ; preds = %if.end172 + store i32 15172, i32* @f, align 4 + br label %if.end176 + +if.end176: ; preds = %if.then175, %if.end172 + br label %if.then179 + +if.then179: ; preds = %if.end176 + store i32 13491, i32* @f, align 4 + br label %if.end180 + +if.end180: ; preds = %if.then179 + %82 = load i32*, i32** @a, align 4 + %arrayidx181 = getelementptr inbounds i32, i32* %82, i32 47 + %83 = load i32, i32* %arrayidx181, align 4 + %tobool182 = icmp ne i32 %83, 0 + br i1 %tobool182, label %if.then183, label %if.end184 + +if.then183: ; preds = %if.end180 + store i32 9521, i32* @f, align 4 + br label %if.end184 + +if.end184: ; preds = %if.then183, %if.end180 + %84 = load i32*, i32** @a, align 4 + %arrayidx185 = getelementptr inbounds i32, i32* %84, i32 48 + %85 = load i32, i32* %arrayidx185, align 4 + %tobool186 = icmp ne i32 %85, 0 + br i1 %tobool186, label %if.then187, label %if.end188 + +if.then187: ; preds = %if.end184 + store i32 448, i32* @f, align 4 + br label %if.end188 + +if.end188: ; preds = %if.then187, %if.end184 + %86 = load i32*, i32** @a, align 4 + %arrayidx189 = getelementptr inbounds i32, i32* %86, i32 49 + %87 = load i32, i32* %arrayidx189, align 4 + %tobool190 = icmp ne i32 %87, 0 + br i1 %tobool190, label %if.then191, label %if.end192 + +if.then191: ; preds = %if.end188 + store i32 13468, i32* @f, align 4 + br label %if.end192 + +if.end192: ; preds = %if.then191, %if.end188 + %88 = load i32*, i32** @a, align 4 + %arrayidx193 = getelementptr inbounds i32, i32* %88, i32 50 + %89 = load i32, i32* %arrayidx193, align 4 + %tobool194 = icmp ne i32 %89, 0 + br i1 %tobool194, label %if.then195, label %if.end196 + +if.then195: ; preds = %if.end192 + store i32 16190, i32* @f, align 4 + br label %if.end196 + +if.end196: ; preds = %if.then195, %if.end192 + %90 = load i32*, i32** @a, align 4 + %arrayidx197 = getelementptr inbounds i32, i32* %90, i32 51 + %91 = load i32, i32* %arrayidx197, align 4 + %tobool198 = icmp ne i32 %91, 0 + br i1 %tobool198, label %if.then199, label %if.end200 + +if.then199: ; preds = %if.end196 + store i32 8602, i32* @f, align 4 + br label %if.end200 + +if.end200: ; preds = %if.then199, %if.end196 + %92 = load i32*, i32** @a, align 4 + %arrayidx201 = getelementptr inbounds i32, i32* %92, i32 52 + %93 = load i32, i32* %arrayidx201, align 4 + %tobool202 = icmp ne i32 %93, 0 + br i1 %tobool202, label %if.then203, label %if.end204 + +if.then203: ; preds = %if.end200 + store i32 21083, i32* @f, align 4 + br label %if.end204 + +if.end204: ; preds = %if.then203, %if.end200 + %94 = load i32*, i32** @a, align 4 + %arrayidx205 = getelementptr inbounds i32, i32* %94, i32 53 + %95 = load i32, i32* %arrayidx205, align 4 + %tobool206 = icmp ne i32 %95, 0 + br i1 %tobool206, label %if.then207, label %if.end208 + +if.then207: ; preds = %if.end204 + store i32 5172, i32* @f, align 4 + br label %if.end208 + +if.end208: ; preds = %if.then207, %if.end204 + %96 = load i32*, i32** @a, align 4 + %arrayidx209 = getelementptr inbounds i32, i32* %96, i32 54 + %97 = load i32, i32* %arrayidx209, align 4 + %tobool210 = icmp ne i32 %97, 0 + br i1 %tobool210, label %if.then211, label %if.end212 + +if.then211: ; preds = %if.end208 + store i32 32505, i32* @f, align 4 + br label %if.end212 + +if.end212: ; preds = %if.then211, %if.end208 + br label %if.then215 + +if.then215: ; preds = %if.end212 + store i32 23490, i32* @f, align 4 + br label %if.end216 + +if.end216: ; preds = %if.then215 + %98 = load i32*, i32** @a, align 4 + %arrayidx217 = getelementptr inbounds i32, i32* %98, i32 56 + %99 = load i32, i32* %arrayidx217, align 4 + %tobool218 = icmp ne i32 %99, 0 + br i1 %tobool218, label %if.then219, label %if.end220 + +if.then219: ; preds = %if.end216 + store i32 30699, i32* @f, align 4 + br label %if.end220 + +if.end220: ; preds = %if.then219, %if.end216 + %100 = load i32*, i32** @a, align 4 + %arrayidx221 = getelementptr inbounds i32, i32* %100, i32 57 + %101 = load i32, i32* %arrayidx221, align 4 + %tobool222 = icmp ne i32 %101, 0 + br i1 %tobool222, label %if.then223, label %if.end224 + +if.then223: ; preds = %if.end220 + store i32 16286, i32* @f, align 4 + br label %if.end224 + +if.end224: ; preds = %if.then223, %if.end220 + %102 = load i32*, i32** @a, align 4 + %arrayidx225 = getelementptr inbounds i32, i32* %102, i32 58 + %103 = load i32, i32* %arrayidx225, align 4 + %tobool226 = icmp ne i32 %103, 0 + br i1 %tobool226, label %if.then227, label %if.end228 + +if.then227: ; preds = %if.end224 + store i32 17939, i32* @f, align 4 + br label %if.end228 + +if.end228: ; preds = %if.then227, %if.end224 + %104 = load i32*, i32** @a, align 4 + %arrayidx229 = getelementptr inbounds i32, i32* %104, i32 59 + %105 = load i32, i32* %arrayidx229, align 4 + %tobool230 = icmp ne i32 %105, 0 + br i1 %tobool230, label %if.then231, label %if.end232 + +if.then231: ; preds = %if.end228 + store i32 25148, i32* @f, align 4 + br label %if.end232 + +if.end232: ; preds = %if.then231, %if.end228 + %106 = load i32*, i32** @a, align 4 + %arrayidx233 = getelementptr inbounds i32, i32* %106, i32 60 + %107 = load i32, i32* %arrayidx233, align 4 + %tobool234 = icmp ne i32 %107, 0 + br i1 %tobool234, label %if.then235, label %if.end236 + +if.then235: ; preds = %if.end232 + store i32 644, i32* @f, align 4 + br label %if.end236 + +if.end236: ; preds = %if.then235, %if.end232 + br label %if.then239 + +if.then239: ; preds = %if.end236 + store i32 23457, i32* @f, align 4 + br label %if.end240 + +if.end240: ; preds = %if.then239 + %108 = load i32*, i32** @a, align 4 + %arrayidx241 = getelementptr inbounds i32, i32* %108, i32 62 + %109 = load i32, i32* %arrayidx241, align 4 + %tobool242 = icmp ne i32 %109, 0 + br i1 %tobool242, label %if.then243, label %if.end244 + +if.then243: ; preds = %if.end240 + store i32 21116, i32* @f, align 4 + br label %if.end244 + +if.end244: ; preds = %if.then243, %if.end240 + br label %if.then247 + +if.then247: ; preds = %if.end244 + store i32 10066, i32* @f, align 4 + br label %if.end248 + +if.end248: ; preds = %if.then247 + %110 = load i32*, i32** @a, align 4 + %arrayidx249 = getelementptr inbounds i32, i32* %110, i32 64 + %111 = load i32, i32* %arrayidx249, align 4 + %tobool250 = icmp ne i32 %111, 0 + br i1 %tobool250, label %if.then251, label %if.end252 + +if.then251: ; preds = %if.end248 + store i32 9058, i32* @f, align 4 + br label %if.end252 + +if.end252: ; preds = %if.then251, %if.end248 + %112 = load i32*, i32** @a, align 4 + %arrayidx253 = getelementptr inbounds i32, i32* %112, i32 65 + %113 = load i32, i32* %arrayidx253, align 4 + %tobool254 = icmp ne i32 %113, 0 + br i1 %tobool254, label %if.then255, label %if.end256 + +if.then255: ; preds = %if.end252 + store i32 8383, i32* @f, align 4 + br label %if.end256 + +if.end256: ; preds = %if.then255, %if.end252 + %114 = load i32*, i32** @a, align 4 + %arrayidx257 = getelementptr inbounds i32, i32* %114, i32 66 + %115 = load i32, i32* %arrayidx257, align 4 + %tobool258 = icmp ne i32 %115, 0 + br i1 %tobool258, label %if.then259, label %if.end260 + +if.then259: ; preds = %if.end256 + store i32 31069, i32* @f, align 4 + br label %if.end260 + +if.end260: ; preds = %if.then259, %if.end256 + %116 = load i32*, i32** @a, align 4 + %arrayidx261 = getelementptr inbounds i32, i32* %116, i32 67 + %117 = load i32, i32* %arrayidx261, align 4 + %tobool262 = icmp ne i32 %117, 0 + br i1 %tobool262, label %if.then263, label %if.end264 + +if.then263: ; preds = %if.end260 + store i32 32280, i32* @f, align 4 + br label %if.end264 + +if.end264: ; preds = %if.then263, %if.end260 + br label %if.then267 + +if.then267: ; preds = %if.end264 + store i32 1553, i32* @f, align 4 + br label %if.end268 + +if.end268: ; preds = %if.then267 + %118 = load i32*, i32** @a, align 4 + %arrayidx269 = getelementptr inbounds i32, i32* %118, i32 69 + %119 = load i32, i32* %arrayidx269, align 4 + %tobool270 = icmp ne i32 %119, 0 + br i1 %tobool270, label %if.then271, label %if.end272 + +if.then271: ; preds = %if.end268 + store i32 8118, i32* @f, align 4 + br label %if.end272 + +if.end272: ; preds = %if.then271, %if.end268 + %120 = load i32*, i32** @a, align 4 + %arrayidx273 = getelementptr inbounds i32, i32* %120, i32 70 + %121 = load i32, i32* %arrayidx273, align 4 + %tobool274 = icmp ne i32 %121, 0 + br i1 %tobool274, label %if.then275, label %if.end276 + +if.then275: ; preds = %if.end272 + store i32 12959, i32* @f, align 4 + br label %if.end276 + +if.end276: ; preds = %if.then275, %if.end272 + %122 = load i32*, i32** @a, align 4 + %arrayidx277 = getelementptr inbounds i32, i32* %122, i32 71 + %123 = load i32, i32* %arrayidx277, align 4 + %tobool278 = icmp ne i32 %123, 0 + br i1 %tobool278, label %if.then279, label %if.end280 + +if.then279: ; preds = %if.end276 + store i32 675, i32* @f, align 4 + br label %if.end280 + +if.end280: ; preds = %if.then279, %if.end276 + %124 = load i32*, i32** @a, align 4 + %arrayidx281 = getelementptr inbounds i32, i32* %124, i32 72 + %125 = load i32, i32* %arrayidx281, align 4 + %tobool282 = icmp ne i32 %125, 0 + br i1 %tobool282, label %if.then283, label %if.end284 + +if.then283: ; preds = %if.end280 + store i32 29144, i32* @f, align 4 + br label %if.end284 + +if.end284: ; preds = %if.then283, %if.end280 + %126 = load i32*, i32** @a, align 4 + %arrayidx285 = getelementptr inbounds i32, i32* %126, i32 73 + %127 = load i32, i32* %arrayidx285, align 4 + %tobool286 = icmp ne i32 %127, 0 + br i1 %tobool286, label %if.then287, label %if.end288 + +if.then287: ; preds = %if.end284 + store i32 26130, i32* @f, align 4 + br label %if.end288 + +if.end288: ; preds = %if.then287, %if.end284 + %128 = load i32*, i32** @a, align 4 + %arrayidx289 = getelementptr inbounds i32, i32* %128, i32 74 + %129 = load i32, i32* %arrayidx289, align 4 + %tobool290 = icmp ne i32 %129, 0 + br i1 %tobool290, label %if.then291, label %if.end292 + +if.then291: ; preds = %if.end288 + store i32 31934, i32* @f, align 4 + br label %if.end292 + +if.end292: ; preds = %if.then291, %if.end288 + %130 = load i32*, i32** @a, align 4 + %arrayidx293 = getelementptr inbounds i32, i32* %130, i32 75 + %131 = load i32, i32* %arrayidx293, align 4 + %tobool294 = icmp ne i32 %131, 0 + br i1 %tobool294, label %if.then295, label %if.end296 + +if.then295: ; preds = %if.end292 + store i32 25862, i32* @f, align 4 + br label %if.end296 + +if.end296: ; preds = %if.then295, %if.end292 + %132 = load i32*, i32** @a, align 4 + %arrayidx297 = getelementptr inbounds i32, i32* %132, i32 76 + %133 = load i32, i32* %arrayidx297, align 4 + %tobool298 = icmp ne i32 %133, 0 + br i1 %tobool298, label %if.then299, label %if.end300 + +if.then299: ; preds = %if.end296 + store i32 10642, i32* @f, align 4 + br label %if.end300 + +if.end300: ; preds = %if.then299, %if.end296 + %134 = load i32*, i32** @a, align 4 + %arrayidx301 = getelementptr inbounds i32, i32* %134, i32 77 + %135 = load i32, i32* %arrayidx301, align 4 + %tobool302 = icmp ne i32 %135, 0 + br i1 %tobool302, label %if.then303, label %if.end304 + +if.then303: ; preds = %if.end300 + store i32 20209, i32* @f, align 4 + br label %if.end304 + +if.end304: ; preds = %if.then303, %if.end300 + %136 = load i32*, i32** @a, align 4 + %arrayidx305 = getelementptr inbounds i32, i32* %136, i32 78 + %137 = load i32, i32* %arrayidx305, align 4 + %tobool306 = icmp ne i32 %137, 0 + br i1 %tobool306, label %if.then307, label %if.end308 + +if.then307: ; preds = %if.end304 + store i32 30889, i32* @f, align 4 + br label %if.end308 + +if.end308: ; preds = %if.then307, %if.end304 + %138 = load i32*, i32** @a, align 4 + %arrayidx309 = getelementptr inbounds i32, i32* %138, i32 79 + %139 = load i32, i32* %arrayidx309, align 4 + %tobool310 = icmp ne i32 %139, 0 + br i1 %tobool310, label %if.then311, label %if.end312 + +if.then311: ; preds = %if.end308 + store i32 18688, i32* @f, align 4 + br label %if.end312 + +if.end312: ; preds = %if.then311, %if.end308 + %140 = load i32*, i32** @a, align 4 + %arrayidx313 = getelementptr inbounds i32, i32* %140, i32 80 + %141 = load i32, i32* %arrayidx313, align 4 + %tobool314 = icmp ne i32 %141, 0 + br i1 %tobool314, label %if.then315, label %if.end316 + +if.then315: ; preds = %if.end312 + store i32 28726, i32* @f, align 4 + br label %if.end316 + +if.end316: ; preds = %if.then315, %if.end312 + %142 = load i32*, i32** @a, align 4 + %arrayidx317 = getelementptr inbounds i32, i32* %142, i32 81 + %143 = load i32, i32* %arrayidx317, align 4 + %tobool318 = icmp ne i32 %143, 0 + br i1 %tobool318, label %if.then319, label %if.end320 + +if.then319: ; preds = %if.end316 + store i32 4266, i32* @f, align 4 + br label %if.end320 + +if.end320: ; preds = %if.then319, %if.end316 + %144 = load i32*, i32** @a, align 4 + %arrayidx321 = getelementptr inbounds i32, i32* %144, i32 82 + %145 = load i32, i32* %arrayidx321, align 4 + %tobool322 = icmp ne i32 %145, 0 + br i1 %tobool322, label %if.then323, label %if.end324 + +if.then323: ; preds = %if.end320 + store i32 15461, i32* @f, align 4 + br label %if.end324 + +if.end324: ; preds = %if.then323, %if.end320 + %146 = load i32*, i32** @a, align 4 + %arrayidx325 = getelementptr inbounds i32, i32* %146, i32 83 + %147 = load i32, i32* %arrayidx325, align 4 + %tobool326 = icmp ne i32 %147, 0 + br i1 %tobool326, label %if.then327, label %if.end328 + +if.then327: ; preds = %if.end324 + store i32 24716, i32* @f, align 4 + br label %if.end328 + +if.end328: ; preds = %if.then327, %if.end324 + br label %if.then331 + +if.then331: ; preds = %if.end328 + store i32 18727, i32* @f, align 4 + br label %if.end332 + +if.end332: ; preds = %if.then331 + %148 = load i32*, i32** @a, align 4 + %arrayidx333 = getelementptr inbounds i32, i32* %148, i32 85 + %149 = load i32, i32* %arrayidx333, align 4 + %tobool334 = icmp ne i32 %149, 0 + br i1 %tobool334, label %if.then335, label %if.end336 + +if.then335: ; preds = %if.end332 + store i32 29505, i32* @f, align 4 + br label %if.end336 + +if.end336: ; preds = %if.then335, %if.end332 + %150 = load i32*, i32** @a, align 4 + %arrayidx337 = getelementptr inbounds i32, i32* %150, i32 86 + %151 = load i32, i32* %arrayidx337, align 4 + %tobool338 = icmp ne i32 %151, 0 + br i1 %tobool338, label %if.then339, label %if.end340 + +if.then339: ; preds = %if.end336 + store i32 27008, i32* @f, align 4 + br label %if.end340 + +if.end340: ; preds = %if.then339, %if.end336 + %152 = load i32*, i32** @a, align 4 + %arrayidx341 = getelementptr inbounds i32, i32* %152, i32 87 + %153 = load i32, i32* %arrayidx341, align 4 + %tobool342 = icmp ne i32 %153, 0 + br i1 %tobool342, label %if.then343, label %if.end344 + +if.then343: ; preds = %if.end340 + store i32 6550, i32* @f, align 4 + br label %if.end344 + +if.end344: ; preds = %if.then343, %if.end340 + br label %if.then347 + +if.then347: ; preds = %if.end344 + store i32 1117, i32* @f, align 4 + br label %if.end348 + +if.end348: ; preds = %if.then347 + %154 = load i32*, i32** @a, align 4 + %arrayidx349 = getelementptr inbounds i32, i32* %154, i32 89 + %155 = load i32, i32* %arrayidx349, align 4 + %tobool350 = icmp ne i32 %155, 0 + br i1 %tobool350, label %if.then351, label %if.end352 + +if.then351: ; preds = %if.end348 + store i32 20118, i32* @f, align 4 + br label %if.end352 + +if.end352: ; preds = %if.then351, %if.end348 + %156 = load i32*, i32** @a, align 4 + %arrayidx353 = getelementptr inbounds i32, i32* %156, i32 90 + %157 = load i32, i32* %arrayidx353, align 4 + %tobool354 = icmp ne i32 %157, 0 + br i1 %tobool354, label %if.then355, label %if.end356 + +if.then355: ; preds = %if.end352 + store i32 13650, i32* @f, align 4 + br label %if.end356 + +if.end356: ; preds = %if.then355, %if.end352 + br label %if.then359 + +if.then359: ; preds = %if.end356 + store i32 18642, i32* @f, align 4 + br label %if.end360 + +if.end360: ; preds = %if.then359 + %158 = load i32*, i32** @a, align 4 + %arrayidx361 = getelementptr inbounds i32, i32* %158, i32 92 + %159 = load i32, i32* %arrayidx361, align 4 + %tobool362 = icmp ne i32 %159, 0 + br i1 %tobool362, label %if.then363, label %if.end364 + +if.then363: ; preds = %if.end360 + store i32 30662, i32* @f, align 4 + br label %if.end364 + +if.end364: ; preds = %if.then363, %if.end360 + %160 = load i32*, i32** @a, align 4 + %arrayidx365 = getelementptr inbounds i32, i32* %160, i32 93 + %161 = load i32, i32* %arrayidx365, align 4 + %tobool366 = icmp ne i32 %161, 0 + br i1 %tobool366, label %if.then367, label %if.end368 + +if.then367: ; preds = %if.end364 + store i32 8095, i32* @f, align 4 + br label %if.end368 + +if.end368: ; preds = %if.then367, %if.end364 + %162 = load i32*, i32** @a, align 4 + %arrayidx369 = getelementptr inbounds i32, i32* %162, i32 94 + %163 = load i32, i32* %arrayidx369, align 4 + %tobool370 = icmp ne i32 %163, 0 + br i1 %tobool370, label %if.then371, label %if.end372 + +if.then371: ; preds = %if.end368 + store i32 8442, i32* @f, align 4 + br label %if.end372 + +if.end372: ; preds = %if.then371, %if.end368 + %164 = load i32*, i32** @a, align 4 + %arrayidx373 = getelementptr inbounds i32, i32* %164, i32 95 + %165 = load i32, i32* %arrayidx373, align 4 + %tobool374 = icmp ne i32 %165, 0 + br i1 %tobool374, label %if.then375, label %if.end376 + +if.then375: ; preds = %if.end372 + store i32 8153, i32* @f, align 4 + br label %if.end376 + +if.end376: ; preds = %if.then375, %if.end372 + br label %if.then379 + +if.then379: ; preds = %if.end376 + store i32 12965, i32* @f, align 4 + br label %if.end380 + +if.end380: ; preds = %if.then379 + %166 = load i32*, i32** @a, align 4 + %arrayidx381 = getelementptr inbounds i32, i32* %166, i32 97 + %167 = load i32, i32* %arrayidx381, align 4 + %tobool382 = icmp ne i32 %167, 0 + br i1 %tobool382, label %if.then383, label %if.end384 + +if.then383: ; preds = %if.end380 + store i32 14277, i32* @f, align 4 + br label %if.end384 + +if.end384: ; preds = %if.then383, %if.end380 + br label %if.then387 + +if.then387: ; preds = %if.end384 + store i32 1997, i32* @f, align 4 + br label %if.end388 + +if.end388: ; preds = %if.then387 + %168 = load i32*, i32** @a, align 4 + %arrayidx389 = getelementptr inbounds i32, i32* %168, i32 99 + %169 = load i32, i32* %arrayidx389, align 4 + %tobool390 = icmp ne i32 %169, 0 + br i1 %tobool390, label %if.then391, label %if.end392 + +if.then391: ; preds = %if.end388 + store i32 31385, i32* @f, align 4 + br label %if.end392 + +if.end392: ; preds = %if.then391, %if.end388 + %170 = load i32*, i32** @a, align 4 + %arrayidx393 = getelementptr inbounds i32, i32* %170, i32 100 + %171 = load i32, i32* %arrayidx393, align 4 + %tobool394 = icmp ne i32 %171, 0 + br i1 %tobool394, label %if.then395, label %if.end396 + +if.then395: ; preds = %if.end392 + store i32 8286, i32* @f, align 4 + br label %if.end396 + +if.end396: ; preds = %if.then395, %if.end392 + ret void +} From ccee5d3d8160abf679a43c362ad4de81fb9ca16b Mon Sep 17 00:00:00 2001 From: Weiming Zhao Date: Thu, 20 Apr 2017 18:37:14 +0000 Subject: [PATCH 4/5] Fix corner cases for compressed jump tables Summary: When synthesized TBB/TBH is expanded, we need to avoid the case of: BaseReg is redefined after the load of branching target. E.g.: %R2 = tLEApcrelJT %R1 = tLDRr %R1, %R2 ==> %R2 = tLEApcrelJT %R2 = tLDRspi %SP, 12 %R2 = tLDRspi %SP, 12 tBR_JTr %R1 tTBB_JT %R2, %R1 ` Reviewers: jmolloy Reviewed By: jmolloy Subscribers: llvm-commits, rengolin Differential Revision: https://reviews.llvm.org/D32250 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@300870 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMConstantIslandPass.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/Target/ARM/ARMConstantIslandPass.cpp b/lib/Target/ARM/ARMConstantIslandPass.cpp index 76df13d6bcd0..083986bd67d2 100644 --- a/lib/Target/ARM/ARMConstantIslandPass.cpp +++ b/lib/Target/ARM/ARMConstantIslandPass.cpp @@ -2094,6 +2094,15 @@ bool ARMConstantIslands::optimizeThumb2JumpTables() { // If we're in PIC mode, there should be another ADD following. auto *TRI = STI->getRegisterInfo(); + + // %base cannot be redefined after the load as it will appear before + // TBB/TBH like: + // %base = + // %base = + // tBB %base, %idx + if (registerDefinedBetween(BaseReg, Load->getNextNode(), MBB->end(), TRI)) + continue; + if (isPositionIndependentOrROPI) { MachineInstr *Add = Load->getNextNode(); if (Add->getOpcode() != ARM::tADDrr || From 46c013e73ec98a94816dd21b15fb6398cf8ff4ec Mon Sep 17 00:00:00 2001 From: Mikael Holmen Date: Wed, 10 May 2017 13:06:13 +0000 Subject: [PATCH 5/5] Add missing check in IfConversion/canFallThroughTo Summary: When trying to figure out if MBB could fallthrough to ToMBB (possibly by falling through a bunch of other MBBs) we didn't actually check if there was fallthrough between the last two blocks in the chain. Reviewers: kparzysz, iteratee, MatzeB Reviewed By: kparzysz, iteratee Subscribers: javed.absar, llvm-commits Differential Revision: https://reviews.llvm.org/D32996 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@302650 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/IfConversion.cpp | 3 +- .../MIR/ARM/ifcvt_canFallThroughTo.mir | 64 +++++++++++++++++++ 2 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 test/CodeGen/MIR/ARM/ifcvt_canFallThroughTo.mir diff --git a/lib/CodeGen/IfConversion.cpp b/lib/CodeGen/IfConversion.cpp index b9f3d86eabd8..dc24d32f9123 100644 --- a/lib/CodeGen/IfConversion.cpp +++ b/lib/CodeGen/IfConversion.cpp @@ -1353,7 +1353,8 @@ static bool canFallThroughTo(MachineBasicBlock &MBB, MachineBasicBlock &ToMBB) { return false; PI = I++; } - return true; + // Finally see if the last I is indeed a successor to PI. + return PI->isSuccessor(&*I); } /// Invalidate predecessor BB info so it would be re-analyzed to determine if it diff --git a/test/CodeGen/MIR/ARM/ifcvt_canFallThroughTo.mir b/test/CodeGen/MIR/ARM/ifcvt_canFallThroughTo.mir new file mode 100644 index 000000000000..5a1583f7a9be --- /dev/null +++ b/test/CodeGen/MIR/ARM/ifcvt_canFallThroughTo.mir @@ -0,0 +1,64 @@ +# RUN: llc -mtriple=arm-apple-ios -o - %s -run-pass if-converter | FileCheck %s +--- +name: f1 +body: | + bb.0: + successors: %bb.1 + + B %bb.1 + + bb.1: + successors: %bb.2, %bb.4 + + Bcc %bb.4, 1, %cpsr + + bb.2: + successors: %bb.3, %bb.5 + + Bcc %bb.5, 1, %cpsr + + bb.3: + successors: %bb.5 + + B %bb.5 + + bb.4: + successors: + + bb.5: + successors: %bb.1, %bb.6 + + Bcc %bb.1, 1, %cpsr + + bb.6: + BX_RET 14, _ + +... + +# IfConversion.cpp/canFallThroughTo thought there was a fallthrough from +# bb.4 to bb5 even if the successor list was empty. +# bb.4 is empty, so it surely looks like it can fallthrough, but this is what +# happens for a bb just containing an "unreachable". + +#CHECK: body: | +#CHECK: bb.0: +#CHECK: successors: %bb.1 + +#CHECK: bb.1: +#CHECK: successors: %bb.3({{.*}}), %bb.2 + +# The original brr_cond from bb.1, jumping to the empty bb +#CHECK: Bcc %bb.2 +#CHECK: B %bb.3 + +# Empty bb.2, originally containing "unreachable" and thus has no successors +#CHECK: bb.2: +#CHECK-NOT: successors + +#CHECK: bb.3: +#CHECK: successors: %bb.1 + +# Conditional BX_RET and then loop back to bb.1 +#CHECK: BX_RET 0 +#CHECK: B %bb.1 +