[PATCH] D54409: PowerPC/SPE: Fix register spilling for SPE registers

Justin Hibbits via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sun Nov 11 14:58:49 PST 2018


jhibbits created this revision.
jhibbits added reviewers: nemanjai, hfinkel, joerg.
Herald added subscribers: llvm-commits, jsji, kbarton.

Pointed out in a comment for https://reviews.llvm.org/D49754, register spilling will currently
spill SPE registers at almost any offset.  However, the instructions
`evstdd` and `evldd` require a) 8-byte alignment, and b) a limit of 256
(unsigned) bytes from the base register, as the offset must fix into a
5-bit offset, which ranges from 0-31 (indexed in double-words).

This enforces the alignment in offsetMinAlign(), and enforces the spill
range check in PPCRegisterInfo::eliminateFrameIndex().

The update to the register spill test is taken partially from the test
case shown in https://reviews.llvm.org/D49754.


Repository:
  rL LLVM

https://reviews.llvm.org/D54409

Files:
  lib/Target/PowerPC/PPCRegisterInfo.cpp
  test/CodeGen/PowerPC/spe.ll


Index: test/CodeGen/PowerPC/spe.ll
===================================================================
--- test/CodeGen/PowerPC/spe.ll
+++ test/CodeGen/PowerPC/spe.ll
@@ -525,18 +525,53 @@
 ; CHECK: #NO_APP
 }
 
-define double @test_spill(double %a) nounwind {
+declare double @test_spill_spe_regs(double, double);
+define dso_local void @test_func2() #0 {
 entry:
+  ret void
+}
+
+ at global_var1 = global i32 0, align 4
+define double @test_spill(double %a, i32 %a1, i64 %a2, i8 * %a3, i32 *%a4, i32* %a5) nounwind {
+entry:
+  %a.addr = alloca double, align 8
+  %a1.addr = alloca i32, align 4
+  %a2.addr = alloca i64, align 8
+  %a3.addr = alloca i8*, align 4
+  %a4.addr = alloca i32*, align 4
+  %a5.addr = alloca i32*, align 4
+  %ptr = alloca i32*, align 4
+  %v1 = alloca [8 x i32], align 4
+  %v2 = alloca [7 x i32], align 4
+  %v3 = alloca [5 x i32], align 4
+  store i32 %a1, i32* %a1.addr, align 4
+  store i64 %a2, i64* %a2.addr, align 8
+  store i8* %a3, i8** %a3.addr, align 4
+  store i32* %a4, i32** %a4.addr, align 4
+  store i32* %a5, i32** %a5.addr, align 4
+  store i32* @global_var1, i32** %ptr, align 4
   %0 = fadd double %a, %a
-  call void asm sideeffect "","~{r0},~{r3},~{s4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15},~{r16},~{r17},~{r18},~{r19},~{r20},~{r21},~{r22},~{r23},~{r24},~{r25},~{r26},~{r27},~{r28},~{r29},~{r30},~{r31}"() nounwind
+  call void asm sideeffect "","~{s0},~{s3},~{s4},~{s5},~{s6},~{s7},~{s8},~{s9},~{s10},~{s11},~{s12},~{s13},~{s14},~{s15},~{s16},~{s17},~{s18},~{s19},~{s20},~{s21},~{s22},~{s23},~{s24},~{s25},~{s26},~{s27},~{s28},~{s29},~{s30},~{s31}"() nounwind
   %1 = fadd double %0, 3.14159
+  %2 = load i32*, i32** %ptr, align 4
+  %3 = bitcast [8 x i32]* %v1 to i8*
+  call void @llvm.memset.p0i8.i32(i8* align 4 %3, i8 0, i32 24, i1 true)
+  %4 = load i32*, i32** %a5.addr, align 4
+  store i32 0, i32* %4, align 4
+  call void @test_func2()
+  %5 = bitcast [7 x i32]* %v2 to i8*
+  call void @llvm.memset.p0i8.i32(i8* align 4 %5, i8 0, i32 20, i1 true)
   br label %return
 
 return:
   ret double %1
 
 ; CHECK-LABEL: test_spill
-; CHECK: efdadd
+; CHECK: li [[VREG:[0-9]+]], 256
+; CHECK: evstddx {{[0-9]+}}, {{[0-9]+}}, [[VREG]]
+; CHECK-NOT: evstdd {{[0-9]+}}, 256({{[0-9]+}}
 ; CHECK: evstdd
+; CHECK: efdadd
 ; CHECK: evldd
 }
+declare void @llvm.memset.p0i8.i32(i8* nocapture writeonly, i8, i32, i1) #1
Index: lib/Target/PowerPC/PPCRegisterInfo.cpp
===================================================================
--- lib/Target/PowerPC/PPCRegisterInfo.cpp
+++ lib/Target/PowerPC/PPCRegisterInfo.cpp
@@ -844,6 +844,9 @@
   case PPC::STXSD:
   case PPC::STXSSP:
     return 4;
+  case PPC::EVLDD:
+  case PPC::EVSTDD:
+    return 8;
   case PPC::LXV:
   case PPC::STXV:
     return 16;
@@ -960,7 +963,10 @@
   // happen in invalid code.
   assert(OpC != PPC::DBG_VALUE &&
          "This should be handled in a target-independent way");
-  if (!noImmForm && ((isInt<16>(Offset) &&
+  bool canBeImmediate = (OpC == PPC::EVSTDD || OpC == PPC::EVLDD) ?
+                        isUInt<8>(Offset) :
+                        isInt<16>(Offset);
+  if (!noImmForm && ((canBeImmediate &&
                       ((Offset % offsetMinAlign(MI)) == 0)) ||
                      OpC == TargetOpcode::STACKMAP ||
                      OpC == TargetOpcode::PATCHPOINT)) {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D54409.173593.patch
Type: text/x-patch
Size: 3356 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20181111/2005fc70/attachment.bin>


More information about the llvm-commits mailing list