[llvm] r326736 - [PowerPC] Do not emit record-form rotates when record-form andi suffices

Nemanja Ivanovic via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 5 11:27:16 PST 2018


Author: nemanjai
Date: Mon Mar  5 11:27:16 2018
New Revision: 326736

URL: http://llvm.org/viewvc/llvm-project?rev=326736&view=rev
Log:
[PowerPC] Do not emit record-form rotates when record-form andi suffices

Up until Power9, the performance profile for rlwinm., rldicl. and andi. looked
more or less equivalent. However with Power9, the rotates are still 2-way
cracked whereas the and-immediate is not.

This patch just ensures that we don't emit record-form rotates when an andi.
is adequate.

As first pointed out by Carrot in https://bugs.llvm.org/show_bug.cgi?id=30833
(this patch is a fix for that PR).

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

Added:
    llvm/trunk/test/CodeGen/PowerPC/noPermuteFormasking.ll
Modified:
    llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp
    llvm/trunk/test/CodeGen/PowerPC/rlwinm-zero-ext.ll

Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp?rev=326736&r1=326735&r2=326736&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp Mon Mar  5 11:27:16 2018
@@ -55,6 +55,8 @@ STATISTIC(CmpIselsConverted,
           "Number of ISELs that depend on comparison of constants converted");
 STATISTIC(MissedConvertibleImmediateInstrs,
           "Number of compare-immediate instructions fed by constants");
+STATISTIC(NumRcRotatesConvertedToRcAnd,
+          "Number of record-form rotates converted to record-form andi");
 
 static cl::
 opt<bool> DisableCTRLoopAnal("disable-ppc-ctrloop-analysis", cl::Hidden,
@@ -1897,6 +1899,31 @@ bool PPCInstrInfo::optimizeCompareInstr(
     // specifically the case if this is the instruction directly after the
     // compare).
 
+    // Rotates are expensive instructions. If we're emitting a record-form
+    // rotate that can just be an andi, we should just emit the andi.
+    if ((MIOpC == PPC::RLWINM || MIOpC == PPC::RLWINM8) &&
+        MI->getOperand(2).getImm() == 0) {
+      int64_t MB = MI->getOperand(3).getImm();
+      int64_t ME = MI->getOperand(4).getImm();
+      if (MB < ME && MB >= 16) {
+        uint64_t Mask = ((1LLU << (32 - MB)) - 1) & ~((1LLU << (31 - ME)) - 1);
+        NewOpC = MIOpC == PPC::RLWINM ? PPC::ANDIo : PPC::ANDIo8;
+        MI->RemoveOperand(4);
+        MI->RemoveOperand(3);
+        MI->getOperand(2).setImm(Mask);
+        NumRcRotatesConvertedToRcAnd++;
+      }
+    } else if (MIOpC == PPC::RLDICL && MI->getOperand(2).getImm() == 0) {
+      int64_t MB = MI->getOperand(3).getImm();
+      if (MB >= 48) {
+        uint64_t Mask = (1LLU << (63 - MB + 1)) - 1;
+        NewOpC = PPC::ANDIo8;
+        MI->RemoveOperand(3);
+        MI->getOperand(2).setImm(Mask);
+        NumRcRotatesConvertedToRcAnd++;
+      }
+    }
+
     const MCInstrDesc &NewDesc = get(NewOpC);
     MI->setDesc(NewDesc);
 

Added: llvm/trunk/test/CodeGen/PowerPC/noPermuteFormasking.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/noPermuteFormasking.ll?rev=326736&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/noPermuteFormasking.ll (added)
+++ llvm/trunk/test/CodeGen/PowerPC/noPermuteFormasking.ll Mon Mar  5 11:27:16 2018
@@ -0,0 +1,42 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mcpu=pwr9 -mtriple=powerpc64le-unkknown-unknown \
+; RUN:   -verify-machineinstrs -O2 < %s | FileCheck %s
+$test = comdat any
+
+; Function Attrs: noinline nounwind
+define void @test() local_unnamed_addr #0 comdat align 2 {
+; CHECK-LABEL: test:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    ld 3, 0(3)
+; CHECK-NEXT:    cmpdi 1, 3, 0
+; CHECK-NEXT:    andi. 4, 3, 3
+; CHECK-NEXT:    crand 20, 2, 5
+; CHECK-NEXT:    isel 3, 0, 3, 20
+; CHECK-NEXT:    addi 3, 3, -1
+; CHECK-NEXT:    cmpldi 3, 3
+; CHECK-NEXT:    bltlr+ 0
+; CHECK-NEXT:  # %bb.1: # %for.body.i.i.i.i.i.i.i
+entry:
+  %0 = load float*, float** undef, align 8
+  %1 = load i64, i64* undef, align 8
+  %add.ptr.i.i.i.i = getelementptr inbounds float, float* %0, i64 undef
+  %2 = ptrtoint float* %add.ptr.i.i.i.i to i64
+  %and.i.i.i.i.i.i.i = and i64 %2, 3
+  %tobool.i.i.i.i.i.i.i = icmp eq i64 %and.i.i.i.i.i.i.i, 0
+  %cmp.i.i.i.i.i.i.i = icmp slt i64 0, %1
+  %3 = and i1 %tobool.i.i.i.i.i.i.i, %cmp.i.i.i.i.i.i.i
+  %spec.select.i.i.i.i.i.i.i = select i1 %3, i64 0, i64 %1
+  %4 = add i64 %spec.select.i.i.i.i.i.i.i, -1
+  %5 = sub i64 %4, 0
+  br label %for.body.i.i.i.i.i.i.i.prol.loopexit
+
+for.body.i.i.i.i.i.i.i.prol.loopexit:             ; preds = %entry
+  %6 = icmp ult i64 %5, 3
+  br i1 %6, label %exitBB, label %for.body.i.i.i.i.i.i.i
+
+for.body.i.i.i.i.i.i.i:                           ; preds = %for.body.i.i.i.i.i.i.i.prol.loopexit
+  unreachable
+
+exitBB: ; preds = %for.body.i.i.i.i.i.i.i.prol.loopexit
+  ret void
+}

Modified: llvm/trunk/test/CodeGen/PowerPC/rlwinm-zero-ext.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/rlwinm-zero-ext.ll?rev=326736&r1=326735&r2=326736&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/rlwinm-zero-ext.ll (original)
+++ llvm/trunk/test/CodeGen/PowerPC/rlwinm-zero-ext.ll Mon Mar  5 11:27:16 2018
@@ -6,7 +6,7 @@ target triple = "powerpc64le-unknown-lin
 define i8 @test1(i32 %a) {
 entry:
 ; CHECK-NOT: rlwinm {{{[0-9]+}}}, {{[0-9]+}}, 0, 24, 27
-; CHECK: rlwinm. [[REG:[0-9]+]], {{[0-9]+}}, 0, 24, 27
+; CHECK: andi. [[REG:[0-9]+]], {{[0-9]+}}, 240
 ; CHECK-NOT: cmplwi [[REG]], 0
 ; CHECK: beq 0
   %0 = and i32 %a, 240




More information about the llvm-commits mailing list