[WebAssembly] Emit a splat for v128 IMPLICIT_DEF
authorThomas Lively <tlively@google.com>
Thu, 20 Dec 2018 04:20:32 +0000 (04:20 +0000)
committerThomas Lively <tlively@google.com>
Thu, 20 Dec 2018 04:20:32 +0000 (04:20 +0000)
Summary:
This is a code size savings and is also important to get runnable code
while engines do not support v128.const.

Reviewers: aheejin, dschuff

Subscribers: sbc100, jgravelle-google, sunfish, llvm-commits

Differential Revision: https://reviews.llvm.org/D55910

llvm-svn: 349724

llvm/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp
llvm/test/CodeGen/WebAssembly/implicit-def.ll

index dc2aab8..efd8dbe 100644 (file)
@@ -98,7 +98,8 @@ static void ImposeStackOrdering(MachineInstr *MI) {
 static void ConvertImplicitDefToConstZero(MachineInstr *MI,
                                           MachineRegisterInfo &MRI,
                                           const TargetInstrInfo *TII,
-                                          MachineFunction &MF) {
+                                          MachineFunction &MF,
+                                          LiveIntervals &LIS) {
   assert(MI->getOpcode() == TargetOpcode::IMPLICIT_DEF);
 
   const auto *RegClass = MRI.getRegClass(MI->getOperand(0).getReg());
@@ -119,10 +120,13 @@ static void ConvertImplicitDefToConstZero(MachineInstr *MI,
         Type::getDoubleTy(MF.getFunction().getContext())));
     MI->addOperand(MachineOperand::CreateFPImm(Val));
   } else if (RegClass == &WebAssembly::V128RegClass) {
-    // TODO: make splat instead of constant
-    MI->setDesc(TII->get(WebAssembly::CONST_V128_v16i8));
-    for (int I = 0; I < 16; ++I)
-      MI->addOperand(MachineOperand::CreateImm(0));
+    unsigned TempReg = MRI.createVirtualRegister(&WebAssembly::I32RegClass);
+    MI->setDesc(TII->get(WebAssembly::SPLAT_v4i32));
+    MI->addOperand(MachineOperand::CreateReg(TempReg, false));
+    MachineInstr *Const = BuildMI(*MI->getParent(), MI, MI->getDebugLoc(),
+                                  TII->get(WebAssembly::CONST_I32), TempReg)
+                              .addImm(0);
+    LIS.InsertMachineInstrInMaps(*Const);
   } else {
     llvm_unreachable("Unexpected reg class");
   }
@@ -895,7 +899,7 @@ bool WebAssemblyRegStackify::runOnMachineFunction(MachineFunction &MF) {
         // to a constant 0 so that the def is explicit, and the push/pop
         // correspondence is maintained.
         if (Insert->getOpcode() == TargetOpcode::IMPLICIT_DEF)
-          ConvertImplicitDefToConstZero(Insert, MRI, TII, MF);
+          ConvertImplicitDefToConstZero(Insert, MRI, TII, MF, LIS);
 
         // We stackified an operand. Add the defining instruction's operands to
         // the worklist stack now to continue to build an ever deeper tree.
index 8f7dcc8..702879c 100644 (file)
@@ -109,8 +109,8 @@ X:                                                ; preds = %0, C
 ; CHECK-LABEL: implicit_def_v4i32:
 ; CHECK: .LBB{{[0-9]+}}_4:{{$}}
 ; CHECK-NEXT: end_block{{$}}
-; CHECK-NEXT: v128.const $push[[R:[0-9]+]]=, 0, 0, 0, 0, 0, 0, 0, 0,
-; CHECK-SAME:                                0, 0, 0, 0, 0, 0, 0, 0{{$}}
+; CHECK-NEXT: i32.const $push[[L0:[0-9]+]]=, 0{{$}}
+; CHECK-NEXT: i32x4.splat $push[[R:[0-9]+]]=, $pop[[L0]]
 ; CHECK-NEXT: return $pop[[R]]{{$}}
 ; CHECK-NEXT: end_function{{$}}
 define <4 x i32> @implicit_def_v4i32() {