OSDN Git Service

[ARM] Check that CPSR does not have other uses
authorDavid Green <david.green@arm.com>
Sun, 17 Mar 2019 21:36:15 +0000 (21:36 +0000)
committerDavid Green <david.green@arm.com>
Sun, 17 Mar 2019 21:36:15 +0000 (21:36 +0000)
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
test/CodeGen/Thumb2/constant-islands-cbz.mir

index 7aefa01..429c2a5 100644 (file)
@@ -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
index d74f572..cb78311 100644 (file)
@@ -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
+
+...