[llvm] r215328 - ARM: correct isPredicable for MULS in ThHUMB mode

Saleem Abdulrasool compnerd at compnerd.org
Sun Aug 10 15:20:38 PDT 2014


Author: compnerd
Date: Sun Aug 10 17:20:37 2014
New Revision: 215328

URL: http://llvm.org/viewvc/llvm-project?rev=215328&view=rev
Log:
ARM: correct isPredicable for MULS in ThHUMB mode

The ARM ARM states that CPSR may not be updated by a MUL in thumb mode.  Due to
an ordering of Thumb 2 Size Reduction and If Conversion, we would end up
generating a THUMB MULS inside an IT block.

The If Conversion pass uses the TTI isPredicable method to ensure that it can
transform a Basic Block.  However, because we only check for IT handling on
Thumb2 functions, we may miss some cases.  Even then, it only validates that the
CPSR is not *live* rather than it is not accessed.  This corrects the handling
for that particular case since the same restriction does not hold on the vast
majority of the instructions.

This does prevent the IfConversion optimization from kicking in in certain
cases, but generating correct code is more valuable.  Addresses PR20555.

Added:
    llvm/trunk/test/CodeGen/ARM/2014-08-04-muls-it.ll
Modified:
    llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp

Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp?rev=215328&r1=215327&r2=215328&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp Sun Aug 10 17:20:37 2014
@@ -518,6 +518,13 @@ bool ARMBaseInstrInfo::DefinesPredicate(
   return Found;
 }
 
+static bool isCPSRDefined(const MachineInstr *MI) {
+  for (const auto &MO : MI->operands())
+    if (MO.isReg() && MO.getReg() == ARM::CPSR && (MO.isDef() || !MO.isDead()))
+      return true;
+  return false;
+}
+
 /// isPredicable - Return true if the specified instruction can be predicated.
 /// By default, this returns true for every instruction with a
 /// PredicateOperand.
@@ -525,6 +532,13 @@ bool ARMBaseInstrInfo::isPredicable(Mach
   if (!MI->isPredicable())
     return false;
 
+  // The ARM Architecture Reference Manual states that the CPSR may only be
+  // accessed by MUL in Thumb mode if it is outside an IT block.  Thus, if CPSR
+  // is defined (or clobbered) by this instruction, it is not predicable.
+  if (MI->getOpcode() == ARM::tMUL || MI->getOpcode() == ARM::t2MUL)
+    if (isCPSRDefined(MI))
+      return false;
+
   ARMFunctionInfo *AFI =
     MI->getParent()->getParent()->getInfo<ARMFunctionInfo>();
 

Added: llvm/trunk/test/CodeGen/ARM/2014-08-04-muls-it.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/2014-08-04-muls-it.ll?rev=215328&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/2014-08-04-muls-it.ll (added)
+++ llvm/trunk/test/CodeGen/ARM/2014-08-04-muls-it.ll Sun Aug 10 17:20:37 2014
@@ -0,0 +1,25 @@
+; RUN: llc -mtriple thumbv7-eabi -arm-restrict-it -filetype asm -o - %s \
+; RUN:    | FileCheck %s
+
+define arm_aapcscc i32 @function(i32 %i, i32 %j) {
+entry:
+  %cmp = icmp eq i32 %i, %j
+  br i1 %cmp, label %if.then, label %if.end
+
+if.then:                                          ; preds = %entry
+  %mul = mul nsw i32 %i, %i
+  br label %if.end
+
+if.end:                                           ; preds = %if.then, %entry
+  %i.addr.0 = phi i32 [ %mul, %if.then ], [ %i, %entry ]
+  ret i32 %i.addr.0
+}
+
+; CHECK-LABEL: function
+; CHECK: cmp r0, r1
+; CHECK: bne [[LABEL:[.*]]]
+; CHECK-NOT: mulseq r0, r0, r0
+; CHECK: [[LABEL]]
+; CHECK: muls r0, r0, r0
+; CHECK: bx lr
+





More information about the llvm-commits mailing list