[llvm] r232486 - Fix R0 use in PowerPC VSX store for FastIsel.

Samuel Antao sfantao at us.ibm.com
Tue Mar 17 08:00:57 PDT 2015


Author: sfantao
Date: Tue Mar 17 10:00:57 2015
New Revision: 232486

URL: http://llvm.org/viewvc/llvm-project?rev=232486&view=rev
Log:
Fix R0 use in PowerPC VSX store for FastIsel.

The VSX stores are sometimes generated with a undefined index register, causing %noreg to be used and R0 to be emitted later on. The semantics of the VSX store (e.g. stdsdx) requires R0 to be used as base if we want zero to be used in the computation of the effective address instead of the content of R0. This patch checks if no index register was generated and forces R0 to be used as base address.

Added:
    llvm/trunk/test/CodeGen/PowerPC/fast-isel-load-store-vsx.ll
Modified:
    llvm/trunk/lib/Target/PowerPC/PPCFastISel.cpp

Modified: llvm/trunk/lib/Target/PowerPC/PPCFastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCFastISel.cpp?rev=232486&r1=232485&r2=232486&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCFastISel.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCFastISel.cpp Tue Mar 17 10:00:57 2015
@@ -675,8 +675,18 @@ bool PPCFastISel::PPCEmitStore(MVT VT, u
       case PPC::STFS: Opc = PPC::STFSX; break;
       case PPC::STFD: Opc = IsVSFRC ? PPC::STXSDX : PPC::STFDX; break;
     }
-    BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc))
-      .addReg(SrcReg).addReg(Addr.Base.Reg).addReg(IndexReg);
+
+    auto MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc))
+        .addReg(SrcReg);
+
+    // If we have an index register defined we use it in the store inst,
+    // otherwise we use X0 as base as it makes the vector instructions to
+    // use zero in the computation of the effective address regardless the
+    // content of the register.
+    if (IndexReg)
+      MIB.addReg(Addr.Base.Reg).addReg(IndexReg);
+    else
+      MIB.addReg(PPC::ZERO8).addReg(Addr.Base.Reg);
   }
 
   return true;

Added: llvm/trunk/test/CodeGen/PowerPC/fast-isel-load-store-vsx.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/fast-isel-load-store-vsx.ll?rev=232486&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/fast-isel-load-store-vsx.ll (added)
+++ llvm/trunk/test/CodeGen/PowerPC/fast-isel-load-store-vsx.ll Tue Mar 17 10:00:57 2015
@@ -0,0 +1,33 @@
+;; There are some known limitations in the VSX support during FastIsel 
+;; (see fast-isel-load-store.ll header). Nevertheless, we are adding some 
+;; regressions here for bugs we fix in the meantime
+; RUN: llc < %s -O0 -fast-isel -mattr=+vsx -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr7 | FileCheck %s --check-prefix=ELF64VSX
+
+;; The semantics of VSX stores for when R0 is used is different depending on
+;; whether it is used as base or offset. If used as base, the effective
+;; address computation will use zero regardless the content of R0. If used as
+;; offset, the content will be used in the effective address. We observed that
+;; for some constructors, the initialization values were being stored without
+;; any offset register being specified which was causing R0 to be used as offset
+;; in regions where it contained the value in the link register. This regression
+;; verifies that R0 is used as base in these situations.
+
+%SomeStruct = type { double }
+
+; ELF64VSX-LABEL: SomeStructCtor
+define linkonce_odr void @SomeStructCtor(%SomeStruct* %this, double %V) unnamed_addr align 2 {
+entry:
+  %this.addr = alloca %SomeStruct*, align 8
+  %V.addr = alloca double, align 8
+  store %SomeStruct* %this, %SomeStruct** %this.addr, align 8
+; ELF64VSX: stxsdx {{[0-9][0-9]?}}, 0, {{[1-9][0-9]?}}
+  store double %V, double* %V.addr, align 8
+  %this1 = load %SomeStruct*, %SomeStruct** %this.addr
+  %Val = getelementptr inbounds %SomeStruct, %SomeStruct* %this1, i32 0, i32 0
+; ELF64VSX: stxsdx {{[0-9][0-9]?}}, 0, {{[1-9][0-9]?}}
+  %0 = load double, double* %V.addr, align 8
+  store double %0, double* %Val, align 8
+  ret void
+ } 
+
+





More information about the llvm-commits mailing list