[llvm] r297871 - ARM: avoid clobbering register in v6 jump-table expansion.
Tim Northover via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 15 11:38:13 PDT 2017
Author: tnorthover
Date: Wed Mar 15 13:38:13 2017
New Revision: 297871
URL: http://llvm.org/viewvc/llvm-project?rev=297871&view=rev
Log:
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.
Added:
llvm/trunk/test/CodeGen/ARM/v6-jumptable-clobber.mir
Modified:
llvm/trunk/include/llvm/CodeGen/MIRYamlMapping.h
llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp
llvm/trunk/lib/CodeGen/MIRPrinter.cpp
llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp
llvm/trunk/test/CodeGen/X86/GlobalISel/irtranslator-call.ll
Modified: llvm/trunk/include/llvm/CodeGen/MIRYamlMapping.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MIRYamlMapping.h?rev=297871&r1=297870&r2=297871&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/MIRYamlMapping.h (original)
+++ llvm/trunk/include/llvm/CodeGen/MIRYamlMapping.h Wed Mar 15 13:38:13 2017
@@ -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<Machine
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);
Modified: llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp?rev=297871&r1=297870&r2=297871&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp (original)
+++ llvm/trunk/lib/CodeGen/MIRParser/MIRParser.cpp Wed Mar 15 13:38:13 2017
@@ -332,6 +332,8 @@ bool MIRParserImpl::initializeMachineFun
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)
Modified: llvm/trunk/lib/CodeGen/MIRPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MIRPrinter.cpp?rev=297871&r1=297870&r2=297871&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MIRPrinter.cpp (original)
+++ llvm/trunk/lib/CodeGen/MIRPrinter.cpp Wed Mar 15 13:38:13 2017
@@ -175,6 +175,8 @@ void MIRPrinter::print(const MachineFunc
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(
Modified: llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp?rev=297871&r1=297870&r2=297871&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMConstantIslandPass.cpp Wed Mar 15 13:38:13 2017
@@ -2104,6 +2104,12 @@ bool ARMConstantIslands::optimizeThumb2J
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;
@@ -2135,14 +2141,14 @@ bool ARMConstantIslands::optimizeThumb2J
// IdxReg gets redefined in the middle of the sequence.
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;
Added: llvm/trunk/test/CodeGen/ARM/v6-jumptable-clobber.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/v6-jumptable-clobber.mir?rev=297871&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/v6-jumptable-clobber.mir (added)
+++ llvm/trunk/test/CodeGen/ARM/v6-jumptable-clobber.mir Wed Mar 15 13:38:13 2017
@@ -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:
+
+...
Modified: llvm/trunk/test/CodeGen/X86/GlobalISel/irtranslator-call.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/GlobalISel/irtranslator-call.ll?rev=297871&r1=297870&r2=297871&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/GlobalISel/irtranslator-call.ll (original)
+++ llvm/trunk/test/CodeGen/X86/GlobalISel/irtranslator-call.ll Wed Mar 15 13:38:13 2017
@@ -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
More information about the llvm-commits
mailing list