[PATCH] D139813: [PowerPC] Improve materialization for immediates which is almost a 32 bit splat.

Esme Yi via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sun Jan 8 17:24:30 PST 2023


Esme updated this revision to Diff 487248.
Esme edited the summary of this revision.
Esme added a comment.

Addressed comments and verified the materialization results.
However, I can't find a proper instruction to turn `0xABCD ADDD ABCD ADDD` into `0xABCD ABCD ABCD ADDD`, ie. modify `Lo16OfHi32 (bits 32...47)`, so I didn't handle the pattern like `0xABCD ABCD ABCD ADDD`.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139813/new/

https://reviews.llvm.org/D139813

Files:
  llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
  llvm/test/CodeGen/PowerPC/constants-i64.ll


Index: llvm/test/CodeGen/PowerPC/constants-i64.ll
===================================================================
--- llvm/test/CodeGen/PowerPC/constants-i64.ll
+++ llvm/test/CodeGen/PowerPC/constants-i64.ll
@@ -391,11 +391,10 @@
 define i64 @imm20() {
 ; CHECK-LABEL: imm20:
 ; CHECK:       # %bb.0: # %entry
-; CHECK-NEXT:  lis 3, -13057
-; CHECK-NEXT:  ori 3, 3, 52479
-; CHECK-NEXT:  rldic 3, 3, 32, 0
-; CHECK-NEXT:  oris 3, 3, 291
+; CHECK-NEXT:  lis 3, 291
 ; CHECK-NEXT:  ori 3, 3, 52479
+; CHECK-NEXT:  rldimi 3, 3, 32, 0
+; CHECK-NEXT:  rldimi 3, 3, 48, 0
 ; CHECK-NEXT:  blr
 entry:
   ret i64 14771750698406366463 ;0xCCFFCCFF0123CCFF
@@ -406,9 +405,8 @@
 ; CHECK:       # %bb.0: # %entry
 ; CHECK-NEXT:  lis 3, -13057
 ; CHECK-NEXT:  ori 3, 3, 291
-; CHECK-NEXT:  rldic 3, 3, 32, 0
-; CHECK-NEXT:  oris 3, 3, 52479
-; CHECK-NEXT:  ori 3, 3, 52479
+; CHECK-NEXT:  rldimi 3, 3, 32, 0
+; CHECK-NEXT:  rlwimi 3, 3, 16, 16, 31
 ; CHECK-NEXT:  blr
 entry:
   ret i64 14771526556073315583 ;0xCCFF0123CCFFCCFF
@@ -419,9 +417,8 @@
 ; CHECK:       # %bb.0: # %entry
 ; CHECK-NEXT:  lis 3, 291
 ; CHECK-NEXT:  ori 3, 3, 52479
-; CHECK-NEXT:  rldic 3, 3, 32, 7
-; CHECK-NEXT:  oris 3, 3, 52479
-; CHECK-NEXT:  ori 3, 3, 52479
+; CHECK-NEXT:  rldimi 3, 3, 32, 0
+; CHECK-NEXT:  rlwimi 3, 3, 16, 0, 15
 ; CHECK-NEXT:  blr
 entry:
   ret i64 82134617250843903 ;0x0123CCFFCCFFCCFF
Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
===================================================================
--- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
+++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
@@ -1328,6 +1328,49 @@
                                     getI32Imm(Lo16));
     ++InstCntDirect;
   }
+
+  // Try to use 4 instructions to materialize the immediate which is "almost" a
+  // splat of a 32 bit immediate.
+  if (InstCntDirect > 4) {
+    uint32_t Hi16OfHi32 = (Hi_32(Imm) >> 16) & 0xffff;
+    uint32_t Lo16OfHi32 = Hi_32(Imm) & 0xffff;
+    uint32_t Hi16OfLo32 = (Lo_32(Imm) >> 16) & 0xffff;
+    uint32_t Lo16OfLo32 = Lo_32(Imm) & 0xffff;
+
+    auto getSplat = [CurDAG, dl, getI32Imm](uint32_t Hi16, uint32_t Lo16) {
+      SDNode *Result =
+          CurDAG->getMachineNode(PPC::LIS8, dl, MVT::i64, getI32Imm(Hi16));
+      Result = CurDAG->getMachineNode(PPC::ORI8, dl, MVT::i64,
+                                      SDValue(Result, 0), getI32Imm(Lo16));
+      SDValue Ops[] = {SDValue(Result, 0), SDValue(Result, 0), getI32Imm(32),
+                       getI32Imm(0)};
+      return CurDAG->getMachineNode(PPC::RLDIMI, dl, MVT::i64, Ops);
+    };
+
+    if (Hi16OfHi32 == Lo16OfHi32 && Lo16OfHi32 == Lo16OfLo32) {
+      InstCntDirect = 4;
+      Result = getSplat(Hi16OfLo32, Lo16OfLo32);
+      // Modify Hi16OfHi32.
+      SDValue Ops[] = {SDValue(Result, 0), SDValue(Result, 0), getI32Imm(48),
+                       getI32Imm(0)};
+      Result = CurDAG->getMachineNode(PPC::RLDIMI, dl, MVT::i64, Ops);
+    } else if (Hi16OfHi32 == Hi16OfLo32 && Hi16OfLo32 == Lo16OfLo32) {
+      InstCntDirect = 4;
+      Result = getSplat(Hi16OfHi32, Lo16OfHi32);
+      // Modify Lo16OfLo32.
+      SDValue Ops[] = {SDValue(Result, 0), SDValue(Result, 0), getI32Imm(16),
+                       getI32Imm(16), getI32Imm(31)};
+      Result = CurDAG->getMachineNode(PPC::RLWIMI8, dl, MVT::i64, Ops);
+    } else if (Lo16OfHi32 == Lo16OfLo32 && Hi16OfLo32 == Lo16OfLo32) {
+      InstCntDirect = 4;
+      Result = getSplat(Hi16OfHi32, Lo16OfHi32);
+      // Modify Hi16OfLo32.
+      SDValue Ops[] = {SDValue(Result, 0), SDValue(Result, 0), getI32Imm(16),
+                       getI32Imm(0), getI32Imm(15)};
+      Result = CurDAG->getMachineNode(PPC::RLWIMI8, dl, MVT::i64, Ops);
+    }
+  }
+
   if (InstCnt)
     *InstCnt = InstCntDirect;
   return Result;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D139813.487248.patch
Type: text/x-patch
Size: 3780 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230109/837c08ee/attachment.bin>


More information about the llvm-commits mailing list