[llvm] bd6033e - [PowerPC] Materialize 34-bit constants with pli directly

Amy Kwan via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 6 11:38:39 PDT 2021


Author: Amy Kwan
Date: 2021-04-06T13:38:11-05:00
New Revision: bd6033eca7be937a236401fdbbf414d6929a44e8

URL: https://github.com/llvm/llvm-project/commit/bd6033eca7be937a236401fdbbf414d6929a44e8
DIFF: https://github.com/llvm/llvm-project/commit/bd6033eca7be937a236401fdbbf414d6929a44e8.diff

LOG: [PowerPC] Materialize 34-bit constants with pli directly

Previously, 34-bit constants were materialized in selectI64Imm(), and we relied
on td pattern matching to instead produce a pli. This becomes problematic as
there is no guarantee that the 34-bit constant will reach the td pattern
selection for pli. It is also possible for other transformations (such as complex
bit permutations) to also produce and utilize the 34-bit constant materialized
through selectI64Imm().

This patch instead produces pli on Power10 directly whenever the constant fits
within 34-bits.

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

Added: 
    

Modified: 
    llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
    llvm/test/CodeGen/PowerPC/p10-constants.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
index dd7b7a345d66d..9ccdc95e9ba49 100644
--- a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
@@ -1059,9 +1059,10 @@ static SDNode *selectI64ImmDirectPrefix(SelectionDAG *CurDAG, const SDLoc &dl,
   InstCnt = 1;
 
   // The pli instruction can materialize up to 34 bits directly.
-  // It is defined in the TD file and so we just return the constant.
+  // If a constant fits within 34-bits, emit the pli instruction here directly.
   if (isInt<34>(Imm))
-    return cast<ConstantSDNode>(CurDAG->getConstant(Imm, dl, MVT::i64));
+    return CurDAG->getMachineNode(PPC::PLI8, dl, MVT::i64,
+                                  CurDAG->getTargetConstant(Imm, dl, MVT::i64));
 
   // Require at least two instructions.
   InstCnt = 2;
@@ -4874,11 +4875,8 @@ void PPCDAGToDAGISel::Select(SDNode *N) {
 
   case ISD::Constant:
     if (N->getValueType(0) == MVT::i64) {
-      SDNode *ResNode = selectI64Imm(CurDAG, N);
-      if (!isa<ConstantSDNode>(ResNode)) {
-        ReplaceNode(N, ResNode);
-        return;
-      }
+      ReplaceNode(N, selectI64Imm(CurDAG, N));
+      return;
     }
     break;
 

diff  --git a/llvm/test/CodeGen/PowerPC/p10-constants.ll b/llvm/test/CodeGen/PowerPC/p10-constants.ll
index dd0619dad17ff..bd70b7bce0f62 100644
--- a/llvm/test/CodeGen/PowerPC/p10-constants.ll
+++ b/llvm/test/CodeGen/PowerPC/p10-constants.ll
@@ -303,6 +303,29 @@ entry:
   ret i64 1129219040652020412
 }
 
+; Producing `pli` when the constant fits within 34-bits and the constant
+; is being produced in other transformations (such as complex bit permutations).
+define i64 @t_34Bits_Complex(i64 %a, i64 %b) {
+; CHECK-LABEL: t_34Bits_Complex:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    rotldi r4, r4, 30
+; CHECK-NEXT:    rldimi r3, r4, 34, 31
+; CHECK-NEXT:    pli r4, -268435457
+; CHECK-NEXT:    and r3, r3, r4
+; CHECK-NEXT:    blr
+;
+; CHECK32-LABEL: t_34Bits_Complex:
+; CHECK32:       # %bb.0: # %entry
+; CHECK32-NEXT:    rlwinm r4, r6, 0, 4, 2
+; CHECK32-NEXT:    rlwimi r3, r5, 0, 31, 29
+; CHECK32-NEXT:    blr
+entry:
+  %and = and i64 %a, 8589934592
+  %and1 = and i64 %b, -8858370049
+  %or = or i64 %and1, %and
+  ret i64 %or
+}
+
 ; The load immediates resulting from phi-nodes are needed to test whether
 ; li/lis is preferred to pli by the instruction selector.
 define dso_local void @t_phiNode() {


        


More information about the llvm-commits mailing list