[PATCH] D45079: [PowerPC] allow D-form load/store when accessing FrameIndex without offset

Hiroshi Inoue via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 30 01:34:18 PDT 2018


inouehrs created this revision.
inouehrs added reviewers: echristo, timshen, kbarton, nemanjai, syzaara, sfertile, lei.

VSX D-form load/store instructions of POWER9 require the offset be a multiple of 16 and a helper`isOffsetMultipleOf` is used to check this.
So far, it handles FrameIndex + offset case, but not handling FrameIndex without offset case. Due to this, we are missing opportunities to exploit D-form instructions when accessing an object or array allocated on stack.
For example, x-form store (stxvx) is used for `int a[4] = {0};` instead of stxv. For larger arrays, D-form instruction is not used when accessing the first 16-byte. Using D-form instructions reduces instructions as well as reducing register pressure.


https://reviews.llvm.org/D45079

Files:
  lib/Target/PowerPC/PPCISelDAGToDAG.cpp
  test/CodeGen/PowerPC/vsx-p9.ll


Index: test/CodeGen/PowerPC/vsx-p9.ll
===================================================================
--- test/CodeGen/PowerPC/vsx-p9.ll
+++ test/CodeGen/PowerPC/vsx-p9.ll
@@ -411,3 +411,34 @@
 }
 
 declare void @sink(...)
+
+; stack object should be accessed using D-form load/store instead of X-form
+define signext i32 @func1() {
+; CHECK-LABEL: @func1
+; CHECK-NOT: stxvx
+; CHECK: blr
+entry:
+  %a = alloca [4 x i32], align 4
+  %0 = bitcast [4 x i32]* %a to i8*
+  call void @llvm.memset.p0i8.i64(i8* nonnull align 4 %0, i8 0, i64 16, i1 false)
+  %arraydecay = getelementptr inbounds [4 x i32], [4 x i32]* %a, i64 0, i64 0
+  %call = call signext i32 @callee(i32* nonnull %arraydecay) #3
+  ret i32 %call
+}
+
+; stack object should be accessed using D-form load/store instead of X-form
+define signext i32 @func2() {
+; CHECK-LABEL: @func2
+; CHECK-NOT: stxvx
+; CHECK: blr
+entry:
+  %a = alloca [16 x i32], align 4
+  %0 = bitcast [16 x i32]* %a to i8*
+  call void @llvm.memset.p0i8.i64(i8* nonnull align 4 %0, i8 0, i64 64, i1 false)
+  %arraydecay = getelementptr inbounds [16 x i32], [16 x i32]* %a, i64 0, i64 0
+  %call = call signext i32 @callee(i32* nonnull %arraydecay) #3
+  ret i32 %call
+}
+
+declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i1) #1
+declare signext i32 @callee(i32*) local_unnamed_addr #2
Index: lib/Target/PowerPC/PPCISelDAGToDAG.cpp
===================================================================
--- lib/Target/PowerPC/PPCISelDAGToDAG.cpp
+++ lib/Target/PowerPC/PPCISelDAGToDAG.cpp
@@ -3951,6 +3951,13 @@
     return isIntS16Immediate(AddrOp.getOperand(1), Imm) && !(Imm % Val);
   }
 
+  // If the address is a frame object without offset, we need to check
+  // the object alignment as we do for a frame index + offset above.
+  if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(AddrOp)) {
+    const MachineFrameInfo &MFI = CurDAG->getMachineFunction().getFrameInfo();
+    return MFI.getObjectAlignment(FI->getIndex()) % Val == 0;
+  }
+
   // If the address comes from the outside, the offset will be zero.
   return AddrOp.getOpcode() == ISD::CopyFromReg;
 }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D45079.140390.patch
Type: text/x-patch
Size: 2140 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180330/4f90d16d/attachment.bin>


More information about the llvm-commits mailing list