[Hexagon] Handle non-immediate constants in HexagonSplitDouble
authorKrzysztof Parzyszek <kparzysz@codeaurora.org>
Fri, 4 May 2018 15:04:48 +0000 (15:04 +0000)
committerKrzysztof Parzyszek <kparzysz@codeaurora.org>
Fri, 4 May 2018 15:04:48 +0000 (15:04 +0000)
llvm-svn: 331527

llvm/lib/Target/Hexagon/HexagonSplitDouble.cpp
llvm/lib/Target/Hexagon/HexagonTargetMachine.cpp
llvm/test/CodeGen/Hexagon/sdr-global.mir [new file with mode: 0644]

index 45b6f71..c0d95ed 100644 (file)
@@ -65,9 +65,7 @@ namespace {
   public:
     static char ID;
 
-    HexagonSplitDoubleRegs() : MachineFunctionPass(ID) {
-      initializeHexagonSplitDoubleRegsPass(*PassRegistry::getPassRegistry());
-    }
+    HexagonSplitDoubleRegs() : MachineFunctionPass(ID) {}
 
     StringRef getPassName() const override {
       return "Hexagon Split Double Registers";
@@ -308,17 +306,16 @@ void HexagonSplitDoubleRegs::partitionRegisters(UUSetMap &P2Rs) {
     P2Rs[I.second].insert(I.first);
 }
 
-static inline int32_t profitImm(unsigned Lo, unsigned Hi) {
+static inline int32_t profitImm(unsigned Imm) {
   int32_t P = 0;
-  if (Lo == 0 || Lo == 0xFFFFFFFF)
-    P += 10;
-  if (Hi == 0 || Hi == 0xFFFFFFFF)
+  if (Imm == 0 || Imm == 0xFFFFFFFF)
     P += 10;
   return P;
 }
 
 int32_t HexagonSplitDoubleRegs::profit(const MachineInstr *MI) const {
   unsigned ImmX = 0;
+dbgs() << *MI;
   unsigned Opc = MI->getOpcode();
   switch (Opc) {
     case TargetOpcode::PHI:
@@ -343,21 +340,28 @@ int32_t HexagonSplitDoubleRegs::profit(const MachineInstr *MI) const {
       uint64_t D = MI->getOperand(1).getImm();
       unsigned Lo = D & 0xFFFFFFFFULL;
       unsigned Hi = D >> 32;
-      return profitImm(LoHi);
+      return profitImm(Lo) + profitImm(Hi);
     }
     case Hexagon::A2_combineii:
-    case Hexagon::A4_combineii:
-      return profitImm(MI->getOperand(1).getImm(),
-                       MI->getOperand(2).getImm());
+    case Hexagon::A4_combineii: {
+      const MachineOperand &Op1 = MI->getOperand(1);
+      const MachineOperand &Op2 = MI->getOperand(2);
+      int32_t Prof1 = Op1.isImm() ? profitImm(Op1.getImm()) : 0;
+      int32_t Prof2 = Op2.isImm() ? profitImm(Op2.getImm()) : 0;
+      return Prof1 + Prof2;
+    }
     case Hexagon::A4_combineri:
       ImmX++;
       // Fall through into A4_combineir.
       LLVM_FALLTHROUGH;
     case Hexagon::A4_combineir: {
       ImmX++;
-      int64_t V = MI->getOperand(ImmX).getImm();
-      if (V == 0 || V == -1)
-        return 10;
+      const MachineOperand &OpX = MI->getOperand(ImmX);
+      if (OpX.isImm()) {
+        int64_t V = OpX.getImm();
+        if (V == 0 || V == -1)
+          return 10;
+      }
       // Fall through into A2_combinew.
       LLVM_FALLTHROUGH;
     }
@@ -735,23 +739,21 @@ void HexagonSplitDoubleRegs::splitCombine(MachineInstr *MI,
   assert(F != PairMap.end());
   const UUPair &P = F->second;
 
-  if (Op1.isImm()) {
+  if (!Op1.isReg()) {
     BuildMI(B, MI, DL, TII->get(Hexagon::A2_tfrsi), P.second)
-      .addImm(Op1.getImm());
-  } else if (Op1.isReg()) {
+      .add(Op1);
+  } else {
     BuildMI(B, MI, DL, TII->get(TargetOpcode::COPY), P.second)
       .addReg(Op1.getReg(), getRegState(Op1), Op1.getSubReg());
-  } else
-    llvm_unreachable("Unexpected operand");
+  }
 
-  if (Op2.isImm()) {
+  if (!Op2.isReg()) {
     BuildMI(B, MI, DL, TII->get(Hexagon::A2_tfrsi), P.first)
-      .addImm(Op2.getImm());
-  } else if (Op2.isReg()) {
+      .add(Op2);
+  } else {
     BuildMI(B, MI, DL, TII->get(TargetOpcode::COPY), P.first)
       .addReg(Op2.getReg(), getRegState(Op2), Op2.getSubReg());
-  } else
-    llvm_unreachable("Unexpected operand");
+  }
 }
 
 void HexagonSplitDoubleRegs::splitExt(MachineInstr *MI,
index cb626eb..2c75e91 100644 (file)
@@ -134,6 +134,7 @@ namespace llvm {
   void initializeHexagonOptAddrModePass(PassRegistry&);
   void initializeHexagonPacketizerPass(PassRegistry&);
   void initializeHexagonRDFOptPass(PassRegistry&);
+  void initializeHexagonSplitDoubleRegsPass(PassRegistry&);
   void initializeHexagonVExtractPass(PassRegistry&);
   Pass *createHexagonLoopIdiomPass();
   Pass *createHexagonVectorLoopCarriedReusePass();
@@ -199,6 +200,7 @@ extern "C" void LLVMInitializeHexagonTarget() {
   initializeHexagonOptAddrModePass(PR);
   initializeHexagonPacketizerPass(PR);
   initializeHexagonRDFOptPass(PR);
+  initializeHexagonSplitDoubleRegsPass(PR);
   initializeHexagonVExtractPass(PR);
 }
 
diff --git a/llvm/test/CodeGen/Hexagon/sdr-global.mir b/llvm/test/CodeGen/Hexagon/sdr-global.mir
new file mode 100644 (file)
index 0000000..dc55a9b
--- /dev/null
@@ -0,0 +1,24 @@
+# RUN: llc -march=hexagon -run-pass hexagon-split-double %s -o - | FileCheck %s
+
+# This used to crash because the constant operand was not an immediate.
+# Make sure we can handle such a case.
+
+# CHECK: = A2_tfrsi 0
+# CHECK: = A2_tfrsi @g0
+
+--- |
+  define i32 @fred() {
+    ret i32 0
+  }
+
+  @g0 = global i32 zeroinitializer
+...
+
+name: fred
+tracksRegLiveness: true
+body: |
+  bb.0:
+    %0:doubleregs = A4_combineir 0, @g0
+    $r0 = COPY %0.isub_lo
+    PS_jmpret $r31, implicit-def $pc, implicit $r0
+...