[llvm-branch-commits] [llvm-branch] r361551 - Merging r351523:

Tom Stellard via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Thu May 23 13:44:15 PDT 2019


Author: tstellar
Date: Thu May 23 13:44:14 2019
New Revision: 361551

URL: http://llvm.org/viewvc/llvm-project?rev=361551&view=rev
Log:
Merging r351523:

------------------------------------------------------------------------
r351523 | dylanmckay | 2019-01-17 22:10:41 -0800 (Thu, 17 Jan 2019) | 12 lines

[AVR] Expand 8/16-bit multiplication to libcalls on MCUs that don't have hardware MUL

This change modifies the LLVM ISel lowering settings so that
8-bit/16-bit multiplication is expanded to calls into the compiler
runtime library if the MCU being targeted does not support
multiplication in hardware.

Before this, MUL instructions would be generated on CPUs like the
ATtiny85, triggering a CPU reset due to an illegal instruction at
runtime.

First raised in https://github.com/avr-rust/rust/issues/124.
------------------------------------------------------------------------

Added:
    llvm/branches/release_80/test/CodeGen/AVR/hardware-mul.ll
    llvm/branches/release_80/test/CodeGen/AVR/software-mul.ll
Removed:
    llvm/branches/release_80/test/CodeGen/AVR/mul.ll
Modified:
    llvm/branches/release_80/lib/Target/AVR/AVRISelLowering.cpp
    llvm/branches/release_80/lib/Target/AVR/AVRISelLowering.h
    llvm/branches/release_80/lib/Target/AVR/AVRSubtarget.cpp
    llvm/branches/release_80/lib/Target/AVR/AVRSubtarget.h
    llvm/branches/release_80/test/CodeGen/AVR/smul-with-overflow.ll
    llvm/branches/release_80/test/CodeGen/AVR/umul-with-overflow.ll

Modified: llvm/branches/release_80/lib/Target/AVR/AVRISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/release_80/lib/Target/AVR/AVRISelLowering.cpp?rev=361551&r1=361550&r2=361551&view=diff
==============================================================================
--- llvm/branches/release_80/lib/Target/AVR/AVRISelLowering.cpp (original)
+++ llvm/branches/release_80/lib/Target/AVR/AVRISelLowering.cpp Thu May 23 13:44:14 2019
@@ -26,19 +26,21 @@
 
 #include "AVR.h"
 #include "AVRMachineFunctionInfo.h"
+#include "AVRSubtarget.h"
 #include "AVRTargetMachine.h"
 #include "MCTargetDesc/AVRMCTargetDesc.h"
 
 namespace llvm {
 
-AVRTargetLowering::AVRTargetLowering(AVRTargetMachine &tm)
-    : TargetLowering(tm) {
+AVRTargetLowering::AVRTargetLowering(const AVRTargetMachine &TM,
+                                     const AVRSubtarget &STI)
+    : TargetLowering(TM), Subtarget(STI) {
   // Set up the register classes.
   addRegisterClass(MVT::i8, &AVR::GPR8RegClass);
   addRegisterClass(MVT::i16, &AVR::DREGSRegClass);
 
   // Compute derived properties from the register classes.
-  computeRegisterProperties(tm.getSubtargetImpl()->getRegisterInfo());
+  computeRegisterProperties(Subtarget.getRegisterInfo());
 
   setBooleanContents(ZeroOrOneBooleanContent);
   setBooleanVectorContents(ZeroOrOneBooleanContent);
@@ -163,6 +165,13 @@ AVRTargetLowering::AVRTargetLowering(AVR
   setOperationAction(ISD::SMUL_LOHI, MVT::i16, Expand);
   setOperationAction(ISD::UMUL_LOHI, MVT::i16, Expand);
 
+  // Expand multiplications to libcalls when there is
+  // no hardware MUL.
+  if (!Subtarget.supportsMultiplication()) {
+    setOperationAction(ISD::SMUL_LOHI, MVT::i8, Expand);
+    setOperationAction(ISD::UMUL_LOHI, MVT::i8, Expand);
+  }
+
   for (MVT VT : MVT::integer_valuetypes()) {
     setOperationAction(ISD::MULHS, VT, Expand);
     setOperationAction(ISD::MULHU, VT, Expand);
@@ -1271,7 +1280,7 @@ SDValue AVRTargetLowering::LowerCall(Tar
 
   // Add a register mask operand representing the call-preserved registers.
   const AVRTargetMachine &TM = (const AVRTargetMachine &)getTargetMachine();
-  const TargetRegisterInfo *TRI = TM.getSubtargetImpl()->getRegisterInfo();
+  const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
   const uint32_t *Mask =
       TRI->getCallPreservedMask(DAG.getMachineFunction(), CallConv);
   assert(Mask && "Missing call preserved mask for calling convention");
@@ -1434,7 +1443,7 @@ MachineBasicBlock *AVRTargetLowering::in
   MachineFunction *F = BB->getParent();
   MachineRegisterInfo &RI = F->getRegInfo();
   const AVRTargetMachine &TM = (const AVRTargetMachine &)getTargetMachine();
-  const TargetInstrInfo &TII = *TM.getSubtargetImpl()->getInstrInfo();
+  const TargetInstrInfo &TII = *Subtarget.getInstrInfo();
   DebugLoc dl = MI.getDebugLoc();
 
   switch (MI.getOpcode()) {
@@ -1575,7 +1584,7 @@ static bool isCopyMulResult(MachineBasic
 MachineBasicBlock *AVRTargetLowering::insertMul(MachineInstr &MI,
                                                 MachineBasicBlock *BB) const {
   const AVRTargetMachine &TM = (const AVRTargetMachine &)getTargetMachine();
-  const TargetInstrInfo &TII = *TM.getSubtargetImpl()->getInstrInfo();
+  const TargetInstrInfo &TII = *Subtarget.getInstrInfo();
   MachineBasicBlock::iterator I(MI);
   ++I; // in any case insert *after* the mul instruction
   if (isCopyMulResult(I))
@@ -1838,9 +1847,6 @@ std::pair<unsigned, const TargetRegister
 AVRTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
                                                 StringRef Constraint,
                                                 MVT VT) const {
-  auto STI = static_cast<const AVRTargetMachine &>(this->getTargetMachine())
-                 .getSubtargetImpl();
-
   // We only support i8 and i16.
   //
   //:FIXME: remove this assert for now since it gets sometimes executed
@@ -1884,8 +1890,8 @@ AVRTargetLowering::getRegForInlineAsmCon
     }
   }
 
-  return TargetLowering::getRegForInlineAsmConstraint(STI->getRegisterInfo(),
-                                                      Constraint, VT);
+  return TargetLowering::getRegForInlineAsmConstraint(
+      Subtarget.getRegisterInfo(), Constraint, VT);
 }
 
 void AVRTargetLowering::LowerAsmOperandForConstraint(SDValue Op,

Modified: llvm/branches/release_80/lib/Target/AVR/AVRISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/release_80/lib/Target/AVR/AVRISelLowering.h?rev=361551&r1=361550&r2=361551&view=diff
==============================================================================
--- llvm/branches/release_80/lib/Target/AVR/AVRISelLowering.h (original)
+++ llvm/branches/release_80/lib/Target/AVR/AVRISelLowering.h Thu May 23 13:44:14 2019
@@ -64,12 +64,14 @@ enum NodeType {
 
 } // end of namespace AVRISD
 
+class AVRSubtarget;
 class AVRTargetMachine;
 
 /// Performs target lowering for the AVR.
 class AVRTargetLowering : public TargetLowering {
 public:
-  explicit AVRTargetLowering(AVRTargetMachine &TM);
+  explicit AVRTargetLowering(const AVRTargetMachine &TM,
+                             const AVRSubtarget &STI);
 
 public:
   MVT getScalarShiftAmountTy(const DataLayout &, EVT LHSTy) const override {
@@ -164,6 +166,10 @@ private:
                           const SDLoc &dl, SelectionDAG &DAG,
                           SmallVectorImpl<SDValue> &InVals) const;
 
+protected:
+
+  const AVRSubtarget &Subtarget;
+
 private:
   MachineBasicBlock *insertShift(MachineInstr &MI, MachineBasicBlock *BB) const;
   MachineBasicBlock *insertMul(MachineInstr &MI, MachineBasicBlock *BB) const;

Modified: llvm/branches/release_80/lib/Target/AVR/AVRSubtarget.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/release_80/lib/Target/AVR/AVRSubtarget.cpp?rev=361551&r1=361550&r2=361551&view=diff
==============================================================================
--- llvm/branches/release_80/lib/Target/AVR/AVRSubtarget.cpp (original)
+++ llvm/branches/release_80/lib/Target/AVR/AVRSubtarget.cpp Thu May 23 13:44:14 2019
@@ -29,9 +29,9 @@
 namespace llvm {
 
 AVRSubtarget::AVRSubtarget(const Triple &TT, const std::string &CPU,
-                           const std::string &FS, AVRTargetMachine &TM)
+                           const std::string &FS, const AVRTargetMachine &TM)
     : AVRGenSubtargetInfo(TT, CPU, FS), InstrInfo(), FrameLowering(),
-      TLInfo(TM), TSInfo(),
+      TLInfo(TM, initializeSubtargetDependencies(CPU, FS, TM)), TSInfo(),
 
       // Subtarget features
       m_hasSRAM(false), m_hasJMPCALL(false), m_hasIJMPCALL(false),
@@ -44,4 +44,12 @@ AVRSubtarget::AVRSubtarget(const Triple
   ParseSubtargetFeatures(CPU, FS);
 }
 
+AVRSubtarget &
+AVRSubtarget::initializeSubtargetDependencies(StringRef CPU, StringRef FS,
+                                              const TargetMachine &TM) {
+  // Parse features string.
+  ParseSubtargetFeatures(CPU, FS);
+  return *this;
+}
+
 } // end of namespace llvm

Modified: llvm/branches/release_80/lib/Target/AVR/AVRSubtarget.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/release_80/lib/Target/AVR/AVRSubtarget.h?rev=361551&r1=361550&r2=361551&view=diff
==============================================================================
--- llvm/branches/release_80/lib/Target/AVR/AVRSubtarget.h (original)
+++ llvm/branches/release_80/lib/Target/AVR/AVRSubtarget.h Thu May 23 13:44:14 2019
@@ -37,7 +37,7 @@ public:
   //! \param FS  The feature string.
   //! \param TM  The target machine.
   AVRSubtarget(const Triple &TT, const std::string &CPU, const std::string &FS,
-               AVRTargetMachine &TM);
+               const AVRTargetMachine &TM);
 
   const AVRInstrInfo *getInstrInfo() const override { return &InstrInfo; }
   const TargetFrameLowering *getFrameLowering() const override { return &FrameLowering; }
@@ -49,6 +49,9 @@ public:
   /// \note Definition of function is auto generated by `tblgen`.
   void ParseSubtargetFeatures(StringRef CPU, StringRef FS);
 
+  AVRSubtarget &initializeSubtargetDependencies(StringRef CPU, StringRef FS,
+                                                const TargetMachine &TM);
+
   // Subtarget feature getters.
   // See AVR.td for details.
   bool hasSRAM() const { return m_hasSRAM; }

Added: llvm/branches/release_80/test/CodeGen/AVR/hardware-mul.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/release_80/test/CodeGen/AVR/hardware-mul.ll?rev=361551&view=auto
==============================================================================
--- llvm/branches/release_80/test/CodeGen/AVR/hardware-mul.ll (added)
+++ llvm/branches/release_80/test/CodeGen/AVR/hardware-mul.ll Thu May 23 13:44:14 2019
@@ -0,0 +1,30 @@
+; RUN: llc -mattr=mul,movw < %s -march=avr | FileCheck %s
+
+; Tests lowering of multiplication to hardware instructions.
+
+define i8 @mult8(i8 %a, i8 %b) {
+; CHECK-LABEL: mult8:
+; CHECK: muls r22, r24
+; CHECK: clr r1
+; CHECK: mov  r24, r0
+  %mul = mul i8 %b, %a
+  ret i8 %mul
+}
+
+define i16 @mult16(i16 %a, i16 %b) {
+; CHECK-LABEL: mult16:
+; CHECK: muls r22, r25
+; CHECK: mov  r18, r0
+; CHECK: mul  r22, r24
+; CHECK: mov  r19, r0
+; CHECK: mov  r20, r1
+; CHECK: clr r1
+; CHECK: add  r20, r18
+; CHECK: muls r23, r24
+; CHECK: clr r1
+; CHECK: mov  r22, r0
+; CHECK: add  r22, r20
+; :TODO: finish after reworking shift instructions
+  %mul = mul nsw i16 %b, %a
+  ret i16 %mul
+}

Removed: llvm/branches/release_80/test/CodeGen/AVR/mul.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/release_80/test/CodeGen/AVR/mul.ll?rev=361550&view=auto
==============================================================================
--- llvm/branches/release_80/test/CodeGen/AVR/mul.ll (original)
+++ llvm/branches/release_80/test/CodeGen/AVR/mul.ll (removed)
@@ -1,28 +0,0 @@
-; RUN: llc -mattr=mul,movw < %s -march=avr | FileCheck %s
-
-define i8 @mult8(i8 %a, i8 %b) {
-; CHECK-LABEL: mult8:
-; CHECK: muls r22, r24
-; CHECK: clr r1
-; CHECK: mov  r24, r0
-  %mul = mul i8 %b, %a
-  ret i8 %mul
-}
-
-define i16 @mult16(i16 %a, i16 %b) {
-; CHECK-LABEL: mult16:
-; CHECK: muls r22, r25
-; CHECK: mov  r18, r0
-; CHECK: mul  r22, r24
-; CHECK: mov  r19, r0
-; CHECK: mov  r20, r1
-; CHECK: clr r1
-; CHECK: add  r20, r18
-; CHECK: muls r23, r24
-; CHECK: clr r1
-; CHECK: mov  r22, r0
-; CHECK: add  r22, r20
-; :TODO: finish after reworking shift instructions
-  %mul = mul nsw i16 %b, %a
-  ret i16 %mul
-}

Modified: llvm/branches/release_80/test/CodeGen/AVR/smul-with-overflow.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/release_80/test/CodeGen/AVR/smul-with-overflow.ll?rev=361551&r1=361550&r2=361551&view=diff
==============================================================================
--- llvm/branches/release_80/test/CodeGen/AVR/smul-with-overflow.ll (original)
+++ llvm/branches/release_80/test/CodeGen/AVR/smul-with-overflow.ll Thu May 23 13:44:14 2019
@@ -1,4 +1,4 @@
-; RUN: llc < %s -march=avr | FileCheck %s
+; RUN: llc -mattr=avr6 < %s -march=avr | FileCheck %s
 
 define i1 @signed_multiplication_did_overflow(i8, i8) unnamed_addr {
 ; CHECK-LABEL: signed_multiplication_did_overflow:

Added: llvm/branches/release_80/test/CodeGen/AVR/software-mul.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/release_80/test/CodeGen/AVR/software-mul.ll?rev=361551&view=auto
==============================================================================
--- llvm/branches/release_80/test/CodeGen/AVR/software-mul.ll (added)
+++ llvm/branches/release_80/test/CodeGen/AVR/software-mul.ll Thu May 23 13:44:14 2019
@@ -0,0 +1,28 @@
+; RUN: llc -mattr=avr6,-mul < %s -march=avr | FileCheck %s
+; RUN: llc -mcpu=attiny85 < %s -march=avr | FileCheck %s
+; RUN: llc -mcpu=ata5272 < %s -march=avr | FileCheck %s
+; RUN: llc -mcpu=attiny861a < %s -march=avr | FileCheck %s
+; RUN: llc -mcpu=at90usb82 < %s -march=avr | FileCheck %s
+
+; Tests lowering of multiplication to compiler support routines.
+
+; CHECK-LABEL: mul8:
+define i8 @mul8(i8 %a, i8 %b) {
+; CHECK: mov  r25, r24
+; CHECK: mov  r24, r22
+; CHECK: mov  r22, r25
+; CHECK: call __mulqi3
+  %mul = mul i8 %b, %a
+  ret i8 %mul
+}
+
+; CHECK-LABEL: mul16:
+define i16 @mul16(i16 %a, i16 %b) {
+; CHECK: movw  r18, r24
+; CHECK: movw  r24, r22
+; CHECK: movw  r22, r18
+; CHECK: call  __mulhi3
+  %mul = mul nsw i16 %b, %a
+  ret i16 %mul
+}
+

Modified: llvm/branches/release_80/test/CodeGen/AVR/umul-with-overflow.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/release_80/test/CodeGen/AVR/umul-with-overflow.ll?rev=361551&r1=361550&r2=361551&view=diff
==============================================================================
--- llvm/branches/release_80/test/CodeGen/AVR/umul-with-overflow.ll (original)
+++ llvm/branches/release_80/test/CodeGen/AVR/umul-with-overflow.ll Thu May 23 13:44:14 2019
@@ -1,4 +1,4 @@
-; RUN: llc < %s -march=avr | FileCheck %s
+; RUN: llc -mattr=avr6 < %s -march=avr | FileCheck %s
 
 define i1 @unsigned_multiplication_did_overflow(i8, i8) unnamed_addr {
 ; CHECK-LABEL: unsigned_multiplication_did_overflow:




More information about the llvm-branch-commits mailing list