96 lines
3.5 KiB
LLVM
96 lines
3.5 KiB
LLVM
; The assertions in this file were autogenerated by
|
|
; utils/update_llc_test_checks.py, but were hand-edited to add the
|
|
; "end_function" lines to prevent the tests from passing when there are
|
|
; superfluous instructions at the end of a function. You can run
|
|
; update_llc_test_checks.py again, but please keep the "end_function" lines
|
|
; intact when you commit.
|
|
|
|
; Wasm, to generate valid code, always internally sets `--trap-unreachable` to 1
|
|
; and `--no-trap-after-noreturn` to 0, and these command lines options, if
|
|
; explicitly given, are ignored. Various combinations of these options should
|
|
; have no effect and should not generate invalid code.
|
|
; RUN: llc < %s -verify-machineinstrs | FileCheck %s
|
|
; RUN: llc < %s -fast-isel -fast-isel-abort=1 -verify-machineinstrs | FileCheck %s
|
|
; RUN: llc < %s -verify-machineinstrs --trap-unreachable | FileCheck %s
|
|
; RUN: llc < %s -fast-isel -fast-isel-abort=1 -verify-machineinstrs --trap-unreachable | FileCheck %s
|
|
; RUN: llc < %s -verify-machineinstrs --trap-unreachable --no-trap-after-noreturn | FileCheck %s
|
|
; RUN: llc < %s -fast-isel -fast-isel-abort=1 -verify-machineinstrs --trap-unreachable --no-trap-after-noreturn | FileCheck %s
|
|
|
|
target triple = "wasm32-unknown-unknown"
|
|
|
|
|
|
; Test that the LLVM trap and debug trap intrinsics are lowered to wasm
|
|
; unreachable.
|
|
|
|
declare void @llvm.trap() cold noreturn nounwind
|
|
declare void @llvm.debugtrap() nounwind
|
|
|
|
define void @trap_ret_void() {
|
|
; CHECK-LABEL: trap_ret_void:
|
|
; CHECK: .functype trap_ret_void () -> ()
|
|
; CHECK-NEXT: # %bb.0:
|
|
; CHECK-NEXT: unreachable
|
|
; CHECK-NEXT: # fallthrough-return
|
|
; CHECK-NEXT: end_function
|
|
call void @llvm.trap()
|
|
ret void
|
|
}
|
|
|
|
define void @debugtrap_ret_void() {
|
|
; CHECK-LABEL: debugtrap_ret_void:
|
|
; CHECK: .functype debugtrap_ret_void () -> ()
|
|
; CHECK-NEXT: # %bb.0:
|
|
; CHECK-NEXT: unreachable
|
|
; CHECK-NEXT: # fallthrough-return
|
|
; CHECK-NEXT: end_function
|
|
call void @llvm.debugtrap()
|
|
ret void
|
|
}
|
|
|
|
; LLVM trap followed by LLVM unreachable could become exactly one wasm
|
|
; unreachable, but two are emitted currently.
|
|
define void @trap_unreacheable() {
|
|
; CHECK-LABEL: trap_unreacheable:
|
|
; CHECK: .functype trap_unreacheable () -> ()
|
|
; CHECK-NEXT: # %bb.0:
|
|
; CHECK-NEXT: unreachable
|
|
; CHECK-NEXT: unreachable
|
|
; CHECK-NEXT: end_function
|
|
call void @llvm.trap()
|
|
unreachable
|
|
}
|
|
|
|
|
|
; Test that LLVM unreachable instruction is lowered to wasm unreachable when
|
|
; necessary to fulfill the wasm operand stack requirements.
|
|
|
|
declare void @ext_func()
|
|
declare i32 @ext_func_i32()
|
|
declare void @ext_never_return() noreturn
|
|
|
|
; LLVM IR's 'unreachable' is translated to Wasm 'unreachable'.
|
|
define i32 @missing_ret_unreachable() {
|
|
; CHECK-LABEL: missing_ret_unreachable:
|
|
; CHECK: .functype missing_ret_unreachable () -> (i32)
|
|
; CHECK-NEXT: # %bb.0:
|
|
; CHECK-NEXT: call ext_func
|
|
; CHECK-NEXT: unreachable
|
|
; CHECK-NEXT: end_function
|
|
call void @ext_func()
|
|
unreachable
|
|
}
|
|
|
|
; This is similar to the above test, but the callee has a 'noreturn' attribute.
|
|
; There is an optimization that removes an 'unreachable' after a noreturn call,
|
|
; but Wasm backend doesn't use it and ignore `--no-trap-after-noreturn`, if
|
|
; given, to generate valid code.
|
|
define i32 @missing_ret_noreturn_unreachable() {
|
|
; CHECK-LABEL: missing_ret_noreturn_unreachable:
|
|
; CHECK: .functype missing_ret_noreturn_unreachable () -> (i32)
|
|
; CHECK-NEXT: # %bb.0:
|
|
; CHECK-NEXT: call ext_never_return
|
|
; CHECK-NEXT: unreachable
|
|
; CHECK-NEXT: end_function
|
|
call void @ext_never_return()
|
|
unreachable
|
|
}
|