[PATCH] D14515: [WebAssembly] Support 'unreachable' expression

Derek Schuff via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 9 14:17:30 PST 2015


dschuff created this revision.
dschuff added a reviewer: sunfish.
dschuff added subscribers: llvm-commits, jfb.
Herald added a subscriber: dschuff.

Lower LLVM's 'unreachable' terminator to ISD::TRAP, and lower ISD::TRAP to
wasm's 'unreachable' expression.

WebAssembly type-checks expressions, but a noreturn function with a
return type that doesn't match the context will cause a check
failure. So we lower LLVM 'unreachable' to ISD::TRAP and then lower that
to WebAssembly's 'unreachable' expression, which typechecks in any
context and causes a trap if executed.

http://reviews.llvm.org/D14515

Files:
  lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
  lib/Target/WebAssembly/WebAssemblyInstrControl.td
  lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
  test/CodeGen/WebAssembly/unreachable.ll

Index: test/CodeGen/WebAssembly/unreachable.ll
===================================================================
--- /dev/null
+++ test/CodeGen/WebAssembly/unreachable.ll
@@ -0,0 +1,34 @@
+; RUN: llc < %s -asm-verbose=false | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -fast-isel | FileCheck %s
+
+; Test that LLVM unreachable instruction and trap intrinsic are lowered to
+; wasm unreachable
+
+target datalayout = "e-p:32:32-i64:64-n32:64-S128"
+target triple = "wasm32-unknown-unknown"
+
+declare void @llvm.trap()
+declare void @llvm.debugtrap()
+declare void @abort()
+
+; CHECK-LABEL: f1:
+; CHECK: call $abort
+; CHECK: unreachable
+define i32 @f1() {
+  call void @abort()
+  unreachable
+}
+
+; CHECK-LABEL: f2:
+; CHECK: unreachable
+define void @f2() {
+  call void @llvm.trap()
+  ret void
+}
+
+; CHECK-LABEL: f3:
+; CHECK: unreachable
+define void @f3() {
+  call void @llvm.debugtrap()
+  ret void
+}
Index: lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
===================================================================
--- lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
+++ lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
@@ -50,6 +50,12 @@
                                : "e-p:32:32-i64:64-n32:64-S128",
                         TT, CPU, FS, Options, RM, CM, OL),
       TLOF(make_unique<WebAssemblyTargetObjectFile>()) {
+  // WebAssembly type-checks expressions, but a noreturn function with a return
+  // type that doesn't match the context will cause a check failure. So we lower
+  // LLVM 'unreachable' to ISD::TRAP and then lower that to WebAssembly's
+  // 'unreachable' expression which is meant for that case.
+  this->Options.TrapUnreachable = true;
+
   initAsmInfo();
 
   // We need a reducible CFG, so disable some optimizations which tend to
Index: lib/Target/WebAssembly/WebAssemblyInstrControl.td
===================================================================
--- lib/Target/WebAssembly/WebAssemblyInstrControl.td
+++ lib/Target/WebAssembly/WebAssemblyInstrControl.td
@@ -60,4 +60,5 @@
   defm : RETURN<F32>;
   defm : RETURN<F64>;
   def RETURN_VOID : I<(outs), (ins), [(WebAssemblyreturn)], "return">;
+  def UNREACHABLE : I<(outs), (ins), [(trap)], "unreachable">;
 } // isReturn = 1, isTerminator = 1, hasCtrlDep = 1, isBarrier = 1
Index: lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
===================================================================
--- lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -172,6 +172,9 @@
   for (auto T : MVT::integer_valuetypes())
     for (auto Ext : {ISD::EXTLOAD, ISD::ZEXTLOAD, ISD::SEXTLOAD})
       setLoadExtAction(Ext, T, MVT::i1, Promote);
+
+  // Trap lowers to wasm unreachable
+  setOperationAction(ISD::TRAP, MVT::Other, Legal);
 }
 
 FastISel *WebAssemblyTargetLowering::createFastISel(


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D14515.39753.patch
Type: text/x-patch
Size: 2874 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20151109/605ee546/attachment.bin>


More information about the llvm-commits mailing list