From 492f1085a465114904f822fe36e737840442dd36 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 10 Dec 2015 00:17:35 +0000 Subject: [PATCH] [WebAssembly] Implement anyext. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@255179 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/WebAssembly/WebAssemblyInstrConv.td | 9 +++++++++ test/CodeGen/WebAssembly/conv.ll | 11 +++++++++++ 2 files changed, 20 insertions(+) diff --git a/lib/Target/WebAssembly/WebAssemblyInstrConv.td b/lib/Target/WebAssembly/WebAssemblyInstrConv.td index 4926b8fd872..931f4a913d0 100644 --- a/lib/Target/WebAssembly/WebAssemblyInstrConv.td +++ b/lib/Target/WebAssembly/WebAssemblyInstrConv.td @@ -26,6 +26,15 @@ def I64_EXTEND_U_I32 : I<(outs I64:$dst), (ins I32:$src), [(set I64:$dst, (zext I32:$src))], "i64.extend_u/i32\t$dst, $src">; +} // defs = [ARGUMENTS] + +// Expand a "don't care" extend into zero-extend (chosen over sign-extend +// somewhat arbitrarily, although it favors popular hardware architectures +// and is conceptually a simpler operation). +def : Pat<(i64 (anyext I32:$src)), (I64_EXTEND_U_I32 I32:$src)>; + +let Defs = [ARGUMENTS] in { + // Conversion from floating point to integer traps on overflow and invalid. let hasSideEffects = 1 in { def I32_TRUNC_S_F32 : I<(outs I32:$dst), (ins F32:$src), diff --git a/test/CodeGen/WebAssembly/conv.ll b/test/CodeGen/WebAssembly/conv.ll index 2674a335a13..76fa38090a1 100644 --- a/test/CodeGen/WebAssembly/conv.ll +++ b/test/CodeGen/WebAssembly/conv.ll @@ -214,3 +214,14 @@ define float @f32_demote_f64(double %x) { %a = fptrunc double %x to float ret float %a } + +; If the high its are unused, LLVM will optimize sext/zext into anyext, which +; we need to patterm-match back to a specific instruction. + +; CHECK-LABEL: anyext: +; CHECK: i64.extend_u/i32 $push0=, $0{{$}} +define i64 @anyext(i32 %x) { + %y = sext i32 %x to i64 + %w = shl i64 %y, 32 + ret i64 %w +} -- 2.34.1