]> granicus.if.org Git - llvm/commitdiff
[PowerPC] Materialize more constants with CR-field set in late peephole
authorNemanja Ivanovic <nemanja.i.ibm@gmail.com>
Fri, 13 Jul 2018 15:21:03 +0000 (15:21 +0000)
committerNemanja Ivanovic <nemanja.i.ibm@gmail.com>
Fri, 13 Jul 2018 15:21:03 +0000 (15:21 +0000)
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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@337008 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/PowerPC/PPCInstrInfo.cpp
test/CodeGen/PowerPC/convert-rr-to-ri-instrs.mir
test/CodeGen/PowerPC/rlwinm_rldicl_to_andi.mir [new file with mode: 0644]

index 540d6932004169c96c806acb109454cddcf1cf35..0a3b969c9c36b67768297676e708b35bc6e3d4d7 100644 (file)
@@ -2480,8 +2480,6 @@ bool PPCInstrInfo::convertToImmediateForm(MachineInstr &MI,
       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::convertToImmediateForm(MachineInstr &MI,
     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::convertToImmediateForm(MachineInstr &MI,
       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::convertToImmediateForm(MachineInstr &MI,
   }
 
   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");
index f2821a735b7cecf82a51c975c6fec7d0d00b8bb4..c9038e87af5abde647ad62be0ba10054a9daa4b3 100644 (file)
@@ -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
diff --git a/test/CodeGen/PowerPC/rlwinm_rldicl_to_andi.mir b/test/CodeGen/PowerPC/rlwinm_rldicl_to_andi.mir
new file mode 100644 (file)
index 0000000..b921bf3
--- /dev/null
@@ -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
+
+...