[llvm] r260987 - [WebAssembly] Insert COPY_LOCAL between CopyToReg and FrameIndex DAG nodes

Derek Schuff via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 16 10:18:36 PST 2016


Author: dschuff
Date: Tue Feb 16 12:18:36 2016
New Revision: 260987

URL: http://llvm.org/viewvc/llvm-project?rev=260987&view=rev
Log:
[WebAssembly] Insert COPY_LOCAL between CopyToReg and FrameIndex DAG nodes

CopyToReg nodes don't support FrameIndex operands. Other targets select
the FI to some LEA-like instruction, but since we don't have that, we
need to insert some kind of instruction that can take an FI operand and
produces a value usable by CopyToReg (i.e. in a vreg). So insert a dummy
copy_local between Op and its FI operand. This results in a redundant
copy which we should optimize away later (maybe in the post-FI-lowering
peephole pass).

Differential Revision: http://reviews.llvm.org/D17213

Modified:
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.h
    llvm/trunk/lib/Target/WebAssembly/known_gcc_test_failures.txt
    llvm/trunk/test/CodeGen/WebAssembly/userstack.ll

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp?rev=260987&r1=260986&r2=260987&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp Tue Feb 16 12:18:36 2016
@@ -114,6 +114,7 @@ WebAssemblyTargetLowering::WebAssemblyTa
   setOperationAction(ISD::DYNAMIC_STACKALLOC, MVTPtr, Expand);
 
   setOperationAction(ISD::FrameIndex, MVT::i32, Custom);
+  setOperationAction(ISD::CopyToReg, MVT::Other, Custom);
 
   // Expand these forms; we pattern-match the forms that we can handle in isel.
   for (auto T : {MVT::i32, MVT::i64, MVT::f32, MVT::f64})
@@ -544,9 +545,34 @@ SDValue WebAssemblyTargetLowering::Lower
     case ISD::FRAMEADDR: // TODO: Make this return the userspace frame address
       fail(DL, DAG, "WebAssembly hasn't implemented __builtin_frame_address");
       return SDValue();
+    case ISD::CopyToReg:
+      return LowerCopyToReg(Op, DAG);
   }
 }
 
+SDValue WebAssemblyTargetLowering::LowerCopyToReg(SDValue Op,
+                                                  SelectionDAG &DAG) const {
+  SDValue Src = Op.getOperand(2);
+  if (isa<FrameIndexSDNode>(Src.getNode())) {
+    // CopyToReg nodes don't support FrameIndex operands. Other targets select
+    // the FI to some LEA-like instruction, but since we don't have that, we
+    // need to insert some kind of instruction that can take an FI operand and
+    // produces a value usable by CopyToReg (i.e. in a vreg). So insert a dummy
+    // copy_local between Op and its FI operand.
+    SDLoc DL(Op);
+    EVT VT = Src.getValueType();
+    SDValue Copy(
+        DAG.getMachineNode(VT == MVT::i32 ? WebAssembly::COPY_LOCAL_I32
+                                          : WebAssembly::COPY_LOCAL_I64,
+                           DL, VT, Src),
+        0);
+    return DAG.getCopyToReg(Op.getOperand(0), DL,
+                            cast<RegisterSDNode>(Op.getOperand(1))->getReg(),
+                            Copy);
+  }
+  return SDValue();
+}
+
 SDValue WebAssemblyTargetLowering::LowerFrameIndex(SDValue Op,
                                                    SelectionDAG &DAG) const {
   int FI = cast<FrameIndexSDNode>(Op)->getIndex();

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.h?rev=260987&r1=260986&r2=260987&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.h (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyISelLowering.h Tue Feb 16 12:18:36 2016
@@ -83,6 +83,7 @@ class WebAssemblyTargetLowering final :
   SDValue LowerBR_JT(SDValue Op, SelectionDAG &DAG) const;
   SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
   SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const;
+  SDValue LowerCopyToReg(SDValue Op, SelectionDAG &DAG) const;
 };
 
 namespace WebAssembly {

Modified: llvm/trunk/lib/Target/WebAssembly/known_gcc_test_failures.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/known_gcc_test_failures.txt?rev=260987&r1=260986&r2=260987&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/known_gcc_test_failures.txt (original)
+++ llvm/trunk/lib/Target/WebAssembly/known_gcc_test_failures.txt Tue Feb 16 12:18:36 2016
@@ -1,32 +1,9 @@
 # Tests which are known to fail from the GCC torture test suite.
 
-# InstrEmitter.cpp:302: unsigned int llvm::InstrEmitter::getVR(llvm::SDValue, DenseMap<llvm::SDValue, unsigned int> &): Assertion `I != VRBaseMap.end() && "Node emitted out of order - late"' failed.
-20000801-2.c
-20000815-1.c
-20011126-2.c
-20030916-1.c
-20050826-2.c
-20090113-1.c
-920501-6.c
-930518-1.c
-980707-1.c
-990127-1.c
-loop-15.c
-loop-ivopts-2.c
-pr20466-1.c
-pr28778.c
-pr33870-1.c
-pr33870.c
-pr38051.c
-pr39100.c
-pr49390.c
-pr53645-2.c
-pr53645.c
-pr59643.c
-
 # WebAssemblyCFGStackify.cpp:458: void PlaceMarkers(llvm::MachineFunction &, const llvm::MachineLoopInfo &, const llvm::WebAssemblyInstrInfo &, llvm::MachineDominatorTree &, llvm::WebAssemblyFunctionInfo &): Assertion `Stack.back() == &MBB && "Loop top should be balanced"' failed.
 20090113-2.c
 20090113-3.c
+loop-15.c
 930628-1.c
 
 
@@ -53,6 +30,12 @@ pr38151.c
 # include/llvm/CodeGen/SelectionDAGNodes.h:800: llvm::SDNode::SDNode(unsigned int, unsigned int, llvm::DebugLoc, llvm::SDVTList, ArrayRef<llvm::SDValue>): Assertion `NumOperands == Ops.size() && "NumOperands wasn't wide enough for its operands!"' failed.
 pr28982b.c
 
+# SelectionDAGNodes.h:943: llvm::SDValue::SDValue(llvm::SDNode *, unsigned int): Assertion `(!Node || ResNo < Node->getNumValues()) && "Invalid result number for the given node!"' failed.
+pr53645.c
+pr53645-2.c
+
+# multiple-entry loops are not supported yet.
+pr38051.c
 
 # Computed gotos are not supported (Cannot select BlockAddress/BRIND)
 20040302-1.c

Modified: llvm/trunk/test/CodeGen/WebAssembly/userstack.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WebAssembly/userstack.ll?rev=260987&r1=260986&r2=260987&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/WebAssembly/userstack.ll (original)
+++ llvm/trunk/test/CodeGen/WebAssembly/userstack.ll Tue Feb 16 12:18:36 2016
@@ -160,4 +160,25 @@ define void @dynamic_static_alloca(i32 %
  ret void
 }
 
+; The use of the alloca in a phi causes a CopyToReg DAG node to be generated,
+; which has to have special handling because CopyToReg can't have a FI operand
+; CHECK-LABEL: copytoreg_fi:
+define void @copytoreg_fi(i1 %cond, i32* %b) {
+entry:
+ ; CHECK: i32.const [[L2:.+]]=, 16
+ ; CHECK-NEXT: i32.sub [[SP:.+]]=, {{.+}}, [[L2]]
+ %addr = alloca i32
+ ; CHECK: i32.const [[OFF:.+]]=, 12
+ ; CHECK-NEXT: i32.add [[ADDR:.+]]=, [[SP]], [[OFF]]
+ ; CHECK-NEXT: copy_local [[COPY:.+]]=, [[ADDR]]
+ br label %body
+body:
+ %a = phi i32* [%addr, %entry], [%b, %body]
+ store i32 1, i32* %a
+ ; CHECK: i32.store {{.*}}, 0([[COPY]]),
+ br i1 %cond, label %body, label %exit
+exit:
+ ret void
+}
+
 ; TODO: test over-aligned alloca




More information about the llvm-commits mailing list