[llvm] r337008 - [PowerPC] Materialize more constants with CR-field set in late peephole

Nemanja Ivanovic via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 13 08:21:03 PDT 2018


Author: nemanjai
Date: Fri Jul 13 08:21:03 2018
New Revision: 337008

URL: http://llvm.org/viewvc/llvm-project?rev=337008&view=rev
Log:
[PowerPC] Materialize more constants with CR-field set in late peephole

Revision r322373 fixed a bug in how we materialize constants when the CR-field
needs to be set.

However the fix is overly conservative. It will only do the transform if
AND-ing the input with the new constant produces the same new constant.
This is of course correct, but not necessarily required.

If there are no futher uses of the constant, the constant can be changed.
If there are no uses of the GPR result, the final result of the materialization
isn't important other than it needs to compare to zero correctly (lt, gt, eq).

Differential revision: https://reviews.llvm.org/D42109

Added:
    llvm/trunk/test/CodeGen/PowerPC/rlwinm_rldicl_to_andi.mir
Modified:
    llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp
    llvm/trunk/test/CodeGen/PowerPC/convert-rr-to-ri-instrs.mir

Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp?rev=337008&r1=337007&r2=337008&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp Fri Jul 13 08:21:03 2018
@@ -2480,8 +2480,6 @@ bool PPCInstrInfo::convertToImmediateFor
       Is64BitLI = Opc != PPC::RLDICL_32;
       NewImm = InVal.getSExtValue();
       SetCR = Opc == PPC::RLDICLo;
-      if (SetCR && (SExtImm & NewImm) != NewImm)
-        return false;
       break;
     }
     return false;
@@ -2495,7 +2493,7 @@ bool PPCInstrInfo::convertToImmediateFor
     int64_t ME = MI.getOperand(4).getImm();
     APInt InVal(32, SExtImm, true);
     InVal = InVal.rotl(SH);
-    // Set the bits (        MB + 32       ) to (        ME + 32       ).
+    // Set the bits (        MB + 32        ) to (        ME + 32        ).
     uint64_t Mask = ((1LLU << (32 - MB)) - 1) & ~((1LLU << (31 - ME)) - 1);
     InVal &= Mask;
     // Can't replace negative values with an LI as that will sign-extend
@@ -2509,8 +2507,6 @@ bool PPCInstrInfo::convertToImmediateFor
       Is64BitLI = Opc == PPC::RLWINM8 || Opc == PPC::RLWINM8o;
       NewImm = InVal.getSExtValue();
       SetCR = Opc == PPC::RLWINMo || Opc == PPC::RLWINM8o;
-      if (SetCR && (SExtImm & NewImm) != NewImm)
-        return false;
       break;
     }
     return false;
@@ -2536,6 +2532,33 @@ bool PPCInstrInfo::convertToImmediateFor
   }
 
   if (ReplaceWithLI) {
+    // We need to be careful with CR-setting instructions we're replacing.
+    if (SetCR) {
+      // We don't know anything about uses when we're out of SSA, so only
+      // replace if the new immediate will be reproduced.
+      bool ImmChanged = (SExtImm & NewImm) != NewImm;
+      if (PostRA && ImmChanged)
+        return false;
+
+      if (!PostRA) {
+        // If the defining load-immediate has no other uses, we can just replace
+        // the immediate with the new immediate.
+        if (MRI->hasOneUse(DefMI->getOperand(0).getReg()))
+          DefMI->getOperand(1).setImm(NewImm);
+
+        // If we're not using the GPR result of the CR-setting instruction, we
+        // just need to and with zero/non-zero depending on the new immediate.
+        else if (MRI->use_empty(MI.getOperand(0).getReg())) {
+          if (NewImm) {
+            assert(Immediate && "Transformation converted zero to non-zero?");
+            NewImm = Immediate;
+          }
+        }
+        else if (ImmChanged)
+          return false;
+      }
+    }
+
     LLVM_DEBUG(dbgs() << "Replacing instruction:\n");
     LLVM_DEBUG(MI.dump());
     LLVM_DEBUG(dbgs() << "Fed by:\n");

Modified: llvm/trunk/test/CodeGen/PowerPC/convert-rr-to-ri-instrs.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/convert-rr-to-ri-instrs.mir?rev=337008&r1=337007&r2=337008&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/convert-rr-to-ri-instrs.mir (original)
+++ llvm/trunk/test/CodeGen/PowerPC/convert-rr-to-ri-instrs.mir Fri Jul 13 08:21:03 2018
@@ -3982,7 +3982,8 @@ body:             |
     %1 = COPY $x4
     %0 = LI8 200
     %2 = RLDICLo %0, 61, 3, implicit-def $cr0
-    ; CHECK-NOT: ANDI
+    ; CHECK: LI8 25
+    ; CHECK: ANDIo8 %0, 25
     ; CHECK-LATE-NOT: andi.
     %3 = COPY killed $cr0
     %4 = ISEL8 %1, %2, %3.sub_eq
@@ -4298,7 +4299,8 @@ body:             |
     %2 = COPY %1.sub_32
     %3 = LI -22
     %4 = RLWINMo %3, 0, 24, 31, implicit-def $cr0
-    ; CHECK: ANDIo %3, 234
+    ; CHECK: LI -22
+    ; CHECK: ANDIo %3, 65514
     ; CHECK-LATE: li 3, -22
     ; CHECK-LATE: andi. 5, 3, 234
     %5 = COPY killed $cr0
@@ -4362,7 +4364,8 @@ body:             |
     %2 = COPY %1.sub_32
     %3 = LI -22
     %4 = RLWINMo %3, 5, 24, 31, implicit-def $cr0
-    ; CHECK-NOT: ANDI
+    ; CHECK: LI -22
+    ; CHECK-NOT: ANDIo8 %3, 65514
     ; CHECK-LATE-NOT: andi.
     %5 = COPY killed $cr0
     %6 = ISEL %2, %3, %5.sub_eq

Added: llvm/trunk/test/CodeGen/PowerPC/rlwinm_rldicl_to_andi.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/rlwinm_rldicl_to_andi.mir?rev=337008&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/rlwinm_rldicl_to_andi.mir (added)
+++ llvm/trunk/test/CodeGen/PowerPC/rlwinm_rldicl_to_andi.mir Fri Jul 13 08:21:03 2018
@@ -0,0 +1,416 @@
+# RUN: llc -run-pass ppc-mi-peepholes -ppc-convert-rr-to-ri %s -o - | FileCheck %s
+# RUN: llc -start-after ppc-mi-peepholes -ppc-late-peephole %s -o - | FileCheck %s --check-prefix=CHECK-LATE
+--- |
+  ; ModuleID = 'rlwinm_rldicl_to_andi.ll'
+  source_filename = "rlwinm_rldicl_to_andi.c"
+  target datalayout = "e-m:e-i64:64-n32:64"
+  target triple = "powerpc64le-unknown-linux-gnu"
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define signext i32 @testRLWINMSingleUseDef(i32 signext %a, i32 signext %b) local_unnamed_addr #0 {
+  entry:
+    %shl.mask = and i32 %a, 1048575
+    %tobool = icmp eq i32 %shl.mask, 0
+    %cond = select i1 %tobool, i32 %a, i32 %b
+    ret i32 %cond
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define signext i32 @testRLWINMNoGPRUseZero(i32 signext %a, i32 signext %b) local_unnamed_addr #0 {
+  entry:
+    %shl.mask = and i32 %a, 1048575
+    %tobool = icmp eq i32 %shl.mask, 0
+    %cond = select i1 %tobool, i32 %a, i32 %b
+    ret i32 %cond
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define signext i32 @testRLWINMNoGPRUseNonZero(i32 signext %a, i32 signext %b) local_unnamed_addr #0 {
+  entry:
+    %shl.mask = and i32 %a, 1048575
+    %tobool = icmp eq i32 %shl.mask, 0
+    %cond = select i1 %tobool, i32 %a, i32 %b
+    ret i32 %cond
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define i64 @testRLDICLSingleUseDef(i64 %a, i64 %b) local_unnamed_addr #0 {
+  entry:
+    %shl.mask = and i64 %a, 4503599627370495
+    %tobool = icmp eq i64 %shl.mask, 0
+    %cond = select i1 %tobool, i64 %a, i64 %b
+    ret i64 %cond
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define i64 @testRLDICLNoGPRUseZero(i64 %a, i64 %b) local_unnamed_addr #0 {
+  entry:
+    %shl.mask = and i64 %a, 4503599627370495
+    %tobool = icmp eq i64 %shl.mask, 0
+    %cond = select i1 %tobool, i64 %a, i64 %b
+    ret i64 %cond
+  }
+  
+  ; Function Attrs: norecurse nounwind readnone
+  define i64 @testRLDICLNoGPRUseNonZero(i64 %a, i64 %b) local_unnamed_addr #0 {
+  entry:
+    %shl.mask = and i64 %a, 4503599627370495
+    %tobool = icmp eq i64 %shl.mask, 0
+    %cond = select i1 %tobool, i64 %a, i64 %b
+    ret i64 %cond
+  }
+  
+  attributes #0 = { norecurse nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="ppc64le" "target-features"="+altivec,+bpermd,+crypto,+direct-move,+extdiv,+htm,+power8-vector,+vsx,-power9-vector,-qpx" "unsafe-fp-math"="false" "use-soft-float"="false" }
+  
+  !llvm.module.flags = !{!0, !1}
+  !llvm.ident = !{!2}
+  
+  !0 = !{i32 1, !"wchar_size", i32 4}
+  !1 = !{i32 7, !"PIC Level", i32 2}
+  !2 = !{!"clang version 7.0.0 (trunk 322378)"}
+
+...
+---
+name:            testRLWINMSingleUseDef
+# CHECK: testRLWINMSingleUseDef
+# CHECK-LATE: testRLWINMSingleUseDef
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 3, class: gprc, preferred-register: '' }
+  - { id: 4, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 5, class: crrc, preferred-register: '' }
+  - { id: 6, class: gprc, preferred-register: '' }
+  - { id: 7, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '$x3', virtual-reg: '%0' }
+  - { reg: '$x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: $x3, $x4
+  
+    %1:g8rc = COPY $x4
+    %0:g8rc = COPY $x3
+    %2:gprc_and_gprc_nor0 = COPY %1.sub_32
+    %3:gprc = LI -11
+    %4:gprc_and_gprc_nor0 = RLWINMo %3, 2, 20, 31, implicit-def $cr0
+    ; CHECK: LI 4055
+    ; CHECK: ANDIo %3, 4055
+    ; CHECK-LATE-NOT: andi.
+    ; CHECK-LATE: rlwinm.
+    %5:crrc = COPY killed $cr0
+    %6:gprc = ISEL %4, %2, %5.sub_eq
+    %7:g8rc = EXTSW_32_64 killed %6
+    $x3 = COPY %7
+    BLR8 implicit $lr8, implicit $rm, implicit $x3
+
+...
+---
+name:            testRLWINMNoGPRUseZero
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 3, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 4, class: gprc, preferred-register: '' }
+  - { id: 5, class: crrc, preferred-register: '' }
+  - { id: 6, class: gprc, preferred-register: '' }
+  - { id: 7, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '$x3', virtual-reg: '%0' }
+  - { reg: '$x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: $x3, $x4
+  
+    %1:g8rc = COPY $x4
+    %0:g8rc = COPY $x3
+    %2:gprc_and_gprc_nor0 = COPY %1.sub_32
+    %3:gprc_and_gprc_nor0 = LI 1
+    %4:gprc = RLWINMo %3, 21, 20, 31, implicit-def $cr0
+    ; CHECK: LI 1
+    ; CHECK: ANDIo %3, 0
+    ; CHECK-LATE: li [[IMM:[0-9]+]], 1
+    ; CHECK-LATE: andi. {{[0-9]+}}, [[IMM]], 0
+    %5:crrc = COPY killed $cr0
+    %6:gprc = ISEL %3, %2, %5.sub_eq
+    %7:g8rc = EXTSW_32_64 killed %6
+    $x3 = COPY %7
+    BLR8 implicit $lr8, implicit $rm, implicit $x3
+
+...
+---
+name:            testRLWINMNoGPRUseNonZero
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc, preferred-register: '' }
+  - { id: 1, class: g8rc, preferred-register: '' }
+  - { id: 2, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 3, class: gprc_and_gprc_nor0, preferred-register: '' }
+  - { id: 4, class: gprc, preferred-register: '' }
+  - { id: 5, class: crrc, preferred-register: '' }
+  - { id: 6, class: gprc, preferred-register: '' }
+  - { id: 7, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '$x3', virtual-reg: '%0' }
+  - { reg: '$x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: $x3, $x4
+  
+    %1:g8rc = COPY $x4
+    %0:g8rc = COPY $x3
+    %2:gprc_and_gprc_nor0 = COPY %1.sub_32
+    %3:gprc_and_gprc_nor0 = LI -11
+    %4:gprc = RLWINMo %3, 2, 20, 31, implicit-def $cr0
+    ; CHECK: LI -11
+    ; CHECK: ANDIo %3, 65525
+    ; CHECK-LATE-NOT: andi.
+    ; CHECK-LATE: rlwinm.
+    %5:crrc = COPY killed $cr0
+    %6:gprc = ISEL %3, %2, %5.sub_eq
+    %7:g8rc = EXTSW_32_64 killed %6
+    $x3 = COPY %7
+    BLR8 implicit $lr8, implicit $rm, implicit $x3
+
+...
+---
+name:            testRLDICLSingleUseDef
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc, preferred-register: '' }
+  - { id: 1, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 2, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 3, class: crrc, preferred-register: '' }
+  - { id: 4, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '$x3', virtual-reg: '%0' }
+  - { reg: '$x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: $x3, $x4
+  
+    %1:g8rc_and_g8rc_nox0 = COPY $x4
+    %0:g8rc = LI8 -11
+    %2:g8rc_and_g8rc_nox0  = RLDICLo %0, 2, 49, implicit-def $cr0
+    ; CHECK: LI8 32727
+    ; CHECK: ANDIo8 %0, 32727
+    ; CHECK-LATE-NOT: andi.
+    ; CHECK-LATE: rldicl.
+    %3:crrc = COPY killed $cr0
+    %4:g8rc = ISEL8 %2, %1, %3.sub_eq
+    $x3 = COPY %4
+    BLR8 implicit $lr8, implicit $rm, implicit $x3
+
+...
+---
+name:            testRLDICLNoGPRUseZero
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 2, class: g8rc, preferred-register: '' }
+  - { id: 3, class: crrc, preferred-register: '' }
+  - { id: 4, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '$x3', virtual-reg: '%0' }
+  - { reg: '$x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: $x3, $x4
+  
+    %1:g8rc_and_g8rc_nox0 = COPY $x4
+    %0:g8rc_and_g8rc_nox0 = LI8 1
+    %2:g8rc = RLDICLo %0, 32, 33, implicit-def $cr0
+    ; CHECK: LI8 1
+    ; CHECK: ANDIo8 %0, 0
+    ; CHECK-LATE: li [[IMM:[0-9]+]], 1
+    ; CHECK-LATE: andi. {{[0-9]+}}, [[IMM]], 0
+    %3:crrc = COPY killed $cr0
+    %4:g8rc = ISEL8 %0, %1, %3.sub_eq
+    $x3 = COPY %4
+    BLR8 implicit $lr8, implicit $rm, implicit $x3
+
+...
+---
+name:            testRLDICLNoGPRUseNonZero
+alignment:       4
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+registers:       
+  - { id: 0, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 1, class: g8rc_and_g8rc_nox0, preferred-register: '' }
+  - { id: 2, class: g8rc, preferred-register: '' }
+  - { id: 3, class: crrc, preferred-register: '' }
+  - { id: 4, class: g8rc, preferred-register: '' }
+liveins:         
+  - { reg: '$x3', virtual-reg: '%0' }
+  - { reg: '$x4', virtual-reg: '%1' }
+frameInfo:       
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    0
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  maxCallFrameSize: 4294967295
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      
+stack:           
+constants:       
+body:             |
+  bb.0.entry:
+    liveins: $x3, $x4
+  
+    %1:g8rc_and_g8rc_nox0 = COPY $x4
+    %0:g8rc_and_g8rc_nox0 = LI8 -11
+    %2:g8rc = RLDICLo %0, 2, 49, implicit-def $cr0
+    ; CHECK: LI8 -11
+    ; CHECK: ANDIo8 %0, 65525
+    ; CHECK-LATE-NOT: andi.
+    ; CHECK-LATE: rldicl.
+    %3:crrc = COPY killed $cr0
+    %4:g8rc = ISEL8 %0, %1, %3.sub_eq
+    $x3 = COPY %4
+    BLR8 implicit $lr8, implicit $rm, implicit $x3
+
+...




More information about the llvm-commits mailing list