]> granicus.if.org Git - llvm/commitdiff
[ARM] Ensure we update the correct flags in the peephole optimiser
authorDavid Green <david.green@arm.com>
Thu, 14 Feb 2019 11:09:24 +0000 (11:09 +0000)
committerDavid Green <david.green@arm.com>
Thu, 14 Feb 2019 11:09:24 +0000 (11:09 +0000)
The Arm peephole optimiser code keeps track of both an MI and a SubAdd that can
be used to optimise away a CMP. In the rare case that both are found and not
ruled-out as valid, we could end up setting the flags on the wrong one.

Instead make sure we are using SubAdd if it exists, as it will be closer to the
CMP.

The testcase here is a little theoretical, with a dead def of cpsr. It should
hopefully show the point.

Differential Revision: https://reviews.llvm.org/D58176

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@354018 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMBaseInstrInfo.cpp
test/CodeGen/Thumb2/peephole-addsub.mir [new file with mode: 0644]

index 9c8fed0e223d11db9e761bdfa310200c9d7322a9..a23ae20858eb4ad82dd2ceb29deaa11c2a534746 100644 (file)
@@ -2825,8 +2825,11 @@ bool ARMBaseInstrInfo::optimizeCompareInstr(
   if (!MI && !SubAdd)
     return false;
 
-  // The single candidate is called MI.
-  if (!MI) MI = SubAdd;
+  // If we found a SubAdd, use it as it will be closer to the CMP
+  if (SubAdd) {
+    MI = SubAdd;
+    IsThumb1 = false;
+  }
 
   // We can't use a predicated instruction - it doesn't always write the flags.
   if (isPredicated(*MI))
diff --git a/test/CodeGen/Thumb2/peephole-addsub.mir b/test/CodeGen/Thumb2/peephole-addsub.mir
new file mode 100644 (file)
index 0000000..f9d7a83
--- /dev/null
@@ -0,0 +1,35 @@
+# RUN: llc -run-pass=peephole-opt -verify-machineinstrs -o - %s | FileCheck %s
+--- |
+  target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
+  target triple = "thumbv7-none-eabi"
+
+  define i32 @test(i32 %a, i32 %b) {
+    unreachable
+  }
+
+...
+---
+name:            test
+tracksRegLiveness: true
+liveins:
+  - { reg: '$r0', virtual-reg: '%0' }
+  - { reg: '$r1', virtual-reg: '%1' }
+body:             |
+  bb.0 (%ir-block.0):
+    liveins: $r0, $r1
+
+    %1:rgpr = COPY $r1
+    %0:rgpr = COPY $r0
+    %2:rgpr = t2MOVi 1, 14, $noreg, $noreg
+    %3:gprnopc = t2ADDrr %0, %1, 14, $noreg, $noreg
+    %4:gprnopc = t2SUBri %3, 0, 14, $noreg, def dead $cpsr
+    t2CMPri killed %3, 0, 14, $noreg, implicit-def $cpsr
+    %5:rgpr = t2MOVCCi %2, 0, 7, $cpsr
+    $r0 = COPY %5
+    tBX_RET 14, $noreg, implicit $r0
+
+# CHECK-LABEL: name: test
+# CHECK:      %3:gprnopc = t2ADDrr %0, %1, 14, $noreg, $noreg
+# CHECK-NEXT: %4:gprnopc = t2SUBri %3, 0, 14, $noreg, def $cpsr
+# CHECK-NEXT: %5:rgpr = t2MOVCCi %2, 0, 7, $cpsr
+...