From b44cf4fdfc9c2fbe46d4581bdff0389b65a4eb0e Mon Sep 17 00:00:00 2001 From: David Green Date: Sun, 17 Mar 2019 21:36:15 +0000 Subject: [PATCH] [ARM] Check that CPSR does not have other uses Fix up rL356335 by checking that CPSR is not read between the compare and the branch. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@356349 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMConstantIslandPass.cpp | 6 +++- test/CodeGen/Thumb2/constant-islands-cbz.mir | 41 ++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/lib/Target/ARM/ARMConstantIslandPass.cpp b/lib/Target/ARM/ARMConstantIslandPass.cpp index 7aefa01f63d..429c2a582bb 100644 --- a/lib/Target/ARM/ARMConstantIslandPass.cpp +++ b/lib/Target/ARM/ARMConstantIslandPass.cpp @@ -1912,13 +1912,17 @@ bool ARMConstantIslands::optimizeThumb2Branches() { if (BrOffset >= DestOffset || (DestOffset - BrOffset) > 126) continue; - // Search backwards to the instruction that defines CSPR + // Search backwards to the instruction that defines CSPR. This may or not + // be a CMP, we check that after this loop. If we find an instruction that + // reads cpsr, we need to keep the original cmp. auto *TRI = STI->getRegisterInfo(); MachineBasicBlock::iterator CmpMI = Br.MI; while (CmpMI != Br.MI->getParent()->begin()) { --CmpMI; if (CmpMI->modifiesRegister(ARM::CPSR, TRI)) break; + if (CmpMI->readsRegister(ARM::CPSR, TRI)) + break; } // Check that this inst is a CMP r[0-7], #0 and that the register diff --git a/test/CodeGen/Thumb2/constant-islands-cbz.mir b/test/CodeGen/Thumb2/constant-islands-cbz.mir index d74f572c377..cb78311206b 100644 --- a/test/CodeGen/Thumb2/constant-islands-cbz.mir +++ b/test/CodeGen/Thumb2/constant-islands-cbz.mir @@ -9,6 +9,7 @@ define i32* @test_notcmp(i32* %x, i32 %y) { ret i32* %x } define i32* @test_killflag_1(i32* %x, i32 %y) { ret i32* %x } define i32* @test_killflag_2(i32* %x, i32 %y) { ret i32* %x } + define i32* @test_cpsr(i32* %x, i32 %y) { ret i32* %x } declare dso_local i32 @c(i32 %x) ... @@ -273,4 +274,44 @@ body: | tBX_RET 14, $noreg, implicit killed $r0 ... +--- +name: test_cpsr +tracksRegLiveness: true +liveins: + - { reg: '$r0', virtual-reg: '' } + - { reg: '$r1', virtual-reg: '' } +body: | + ; CHECK-LABEL: name: test_cpsr + ; CHECK: bb.0: + ; CHECK: successors: %bb.2(0x30000000), %bb.1(0x50000000) + ; CHECK: tCMPi8 renamable $r0, 0, 14, $noreg, implicit-def $cpsr + ; CHECK: t2IT 0, 8, implicit-def $itstate + ; CHECK: renamable $r1 = t2ADDri killed renamable $r1, 1, 1, $cpsr, $noreg, implicit killed $itstate + ; CHECK: tBcc %bb.2, 0, killed $cpsr + ; CHECK: bb.1: + ; CHECK: renamable $r0 = tLDRi killed renamable $r0, 0, 14, $noreg :: (load 4 from %ir.x) + ; CHECK: tTAILJMPdND @c, 14, $noreg, implicit $sp, implicit $sp, implicit killed $r0 + ; CHECK: bb.2: + ; CHECK: $r0, dead $cpsr = tMOVi8 0, 14, $noreg + ; CHECK: tBX_RET 14, $noreg, implicit killed $r0 + bb.0: + successors: %bb.1(0x30000000), %bb.2(0x50000000) + liveins: $r0, $r1 + + tCMPi8 renamable $r0, 0, 14, $noreg, implicit-def $cpsr + t2IT 0, 8, implicit-def $itstate + renamable $r1 = t2ADDri killed renamable $r1, 1, 1, $cpsr, $noreg, implicit killed $itstate + t2Bcc %bb.1, 0, killed $cpsr + + bb.2: + liveins: $r0 + + renamable $r0 = tLDRi killed renamable $r0, 0, 14, $noreg :: (load 4 from %ir.x) + tTAILJMPdND @c, 14, $noreg, implicit $sp, implicit $sp, implicit killed $r0 + + bb.1: + $r0, dead $cpsr = tMOVi8 0, 14, $noreg + tBX_RET 14, $noreg, implicit killed $r0 + +... -- 2.11.0