Index: lib/Target/WebAssembly/WebAssemblyRegStackify.cpp =================================================================== --- lib/Target/WebAssembly/WebAssemblyRegStackify.cpp +++ lib/Target/WebAssembly/WebAssemblyRegStackify.cpp @@ -118,6 +118,11 @@ ConstantFP *Val = cast(Constant::getNullValue( 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)); } else { llvm_unreachable("Unexpected reg class"); } Index: test/CodeGen/WebAssembly/implicit-def.ll =================================================================== --- test/CodeGen/WebAssembly/implicit-def.ll +++ test/CodeGen/WebAssembly/implicit-def.ll @@ -1,50 +1,133 @@ -; RUN: llc -o - %s -asm-verbose=false -wasm-keep-registers | FileCheck %s +; RUN: llc -o - %s -asm-verbose=false -wasm-keep-registers -disable-wasm-fallthrough-return-opt -mattr=+simd128 | FileCheck %s + target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" target triple = "wasm32-unknown-unknown" ; Test that stackified IMPLICIT_DEF instructions are converted into -; CONST_I32 to provide an explicit push. - -; CHECK: br_if 2, -; CHECK: i32.const $push[[L0:[0-9]+]]=, 0{{$}} -; CHECK-NEXT: return $pop[[L0]]{{$}} -define i1 @f() { - %a = xor i1 0, 0 - switch i1 %a, label %C [ - i1 0, label %A - i1 1, label %B - ] - -A: - %b = xor i1 0, 0 +; CONST_XXX instructions to provide an explicit push. + +; CHECK-LABEL: implicit_def_i32: +; CHECK: .LBB{{[0-9]+}}_4:{{$}} +; CHECK-NEXT: end_block{{$}} +; CHECK-NEXT: i32.const $push[[R:[0-9]+]]=, 0{{$}} +; CHECK-NEXT: return $pop[[R]]{{$}} +; CHECK-NEXT: end_function{{$}} +define i32 @implicit_def_i32() { + br i1 undef, label %A, label %X + +A: ; preds = %0 + %d = icmp slt i1 0, 0 + br i1 %d, label %C, label %B + +B: ; preds = %A + br label %C + +C: ; preds = %B, %A + %h = phi i32 [ undef, %A ], [ 0, %B ] + br label %X + +X: ; preds = %0, C + %i = phi i32 [ 1, %0 ], [ %h, %C ] + ret i32 %i +} + +; CHECK-LABEL: implicit_def_i64: +; CHECK: .LBB{{[0-9]+}}_4:{{$}} +; CHECK-NEXT: end_block{{$}} +; CHECK-NEXT: i64.const $push[[R:[0-9]+]]=, 0{{$}} +; CHECK-NEXT: return $pop[[R]]{{$}} +; CHECK-NEXT: end_function{{$}} +define i64 @implicit_def_i64() { + br i1 undef, label %A, label %X + +A: ; preds = %0 + %d = icmp slt i1 0, 0 + br i1 %d, label %C, label %B + +B: ; preds = %A + br label %C + +C: ; preds = %B, %A + %h = phi i64 [ undef, %A ], [ 0, %B ] br label %X -B: - %c = xor i1 0, 0 - br i1 %c, label %D, label %X +X: ; preds = %0, C + %i = phi i64 [ 1, %0 ], [ %h, %C ] + ret i64 %i +} + +; CHECK-LABEL: implicit_def_f32: +; CHECK: .LBB{{[0-9]+}}_4:{{$}} +; CHECK-NEXT: end_block{{$}} +; CHECK-NEXT: f32.const $push[[R:[0-9]+]]=, 0x0p0{{$}} +; CHECK-NEXT: return $pop[[R]]{{$}} +; CHECK-NEXT: end_function{{$}} +define float @implicit_def_f32() { + br i1 undef, label %A, label %X -C: - %d = icmp slt i32 0, 0 - br i1 %d, label %G, label %F +A: ; preds = %0 + %d = icmp slt i1 0, 0 + br i1 %d, label %C, label %B -D: - %e = xor i1 0, 0 - br i1 %e, label %E, label %X +B: ; preds = %A + br label %C -E: - %f = xor i1 0, 0 +C: ; preds = %B, %A + %h = phi float [ undef, %A ], [ 0.0, %B ] br label %X -F: - %g = xor i1 0, 0 - br label %G +X: ; preds = %0, C + %i = phi float [ 1.0, %0 ], [ %h, %C ] + ret float %i +} + +; CHECK-LABEL: implicit_def_f64: +; CHECK: .LBB{{[0-9]+}}_4:{{$}} +; CHECK-NEXT: end_block{{$}} +; CHECK-NEXT: f64.const $push[[R:[0-9]+]]=, 0x0p0{{$}} +; CHECK-NEXT: return $pop[[R]]{{$}} +; CHECK-NEXT: end_function{{$}} +define double @implicit_def_f64() { + br i1 undef, label %A, label %X + +A: ; preds = %0 + %d = icmp slt i1 0, 0 + br i1 %d, label %C, label %B + +B: ; preds = %A + br label %C -G: - %h = phi i1 [ undef, %C ], [ false, %F ] +C: ; preds = %B, %A + %h = phi double [ undef, %A ], [ 0.0, %B ] br label %X -X: - %i = phi i1 [ true, %A ], [ true, %B ], [ true, %D ], [ true, %E ], [ %h, %G ] - ret i1 %i +X: ; preds = %0, C + %i = phi double [ 1.0, %0 ], [ %h, %C ] + ret double %i } +; 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: return $pop[[R]]{{$}} +; CHECK-NEXT: end_function{{$}} +define <4 x i32> @implicit_def_v4i32() { + br i1 undef, label %A, label %X + +A: ; preds = %0 + %d = icmp slt i1 0, 0 + br i1 %d, label %C, label %B + +B: ; preds = %A + br label %C + +C: ; preds = %B, %A + %h = phi <4 x i32> [ undef, %A ], [ , %B ] + br label %X + +X: ; preds = %0, C + %i = phi <4 x i32> [ , %0 ], [ %h, %C ] + ret <4 x i32> %i +}