mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
[WebAssembly] Don't abort on code with UB.
Gracefully leave code that performs function-pointer bitcasts implying non-trivial pointer conversions alone, rather than aborting, since it's just undefined behavior. llvm-svn: 291326
This commit is contained in:
parent
278666eda3
commit
f98e4f70d1
@ -77,6 +77,9 @@ static void FindUses(Value *V, Function &F,
|
||||
// - Call with fewer arguments than needed: arguments are filled in with undef
|
||||
// - Return value is not needed: drop it
|
||||
// - Return value needed but not present: supply an undef
|
||||
//
|
||||
// For now, return nullptr without creating a wrapper if the wrapper cannot
|
||||
// be generated due to incompatible types.
|
||||
static Function *CreateWrapper(Function *F, FunctionType *Ty) {
|
||||
Module *M = F->getParent();
|
||||
|
||||
@ -90,8 +93,10 @@ static Function *CreateWrapper(Function *F, FunctionType *Ty) {
|
||||
FunctionType::param_iterator PI = F->getFunctionType()->param_begin();
|
||||
FunctionType::param_iterator PE = F->getFunctionType()->param_end();
|
||||
for (; AI != Wrapper->arg_end() && PI != PE; ++AI, ++PI) {
|
||||
assert(AI->getType() == *PI &&
|
||||
"mismatched argument types not supported yet");
|
||||
if (AI->getType() != *PI) {
|
||||
Wrapper->eraseFromParent();
|
||||
return nullptr;
|
||||
}
|
||||
Args.push_back(&*AI);
|
||||
}
|
||||
for (; PI != PE; ++PI)
|
||||
@ -107,8 +112,10 @@ static Function *CreateWrapper(Function *F, FunctionType *Ty) {
|
||||
BB);
|
||||
else if (F->getFunctionType()->getReturnType() == Ty->getReturnType())
|
||||
ReturnInst::Create(M->getContext(), Call, BB);
|
||||
else
|
||||
llvm_unreachable("mismatched return types not supported yet");
|
||||
else {
|
||||
Wrapper->eraseFromParent();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return Wrapper;
|
||||
}
|
||||
@ -138,10 +145,14 @@ bool FixFunctionBitcasts::runOnModule(Module &M) {
|
||||
if (Pair.second)
|
||||
Pair.first->second = CreateWrapper(F, Ty);
|
||||
|
||||
Function *Wrapper = Pair.first->second;
|
||||
if (!Wrapper)
|
||||
continue;
|
||||
|
||||
if (isa<Constant>(U->get()))
|
||||
U->get()->replaceAllUsesWith(Pair.first->second);
|
||||
U->get()->replaceAllUsesWith(Wrapper);
|
||||
else
|
||||
U->set(Pair.first->second);
|
||||
U->set(Wrapper);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -8,7 +8,7 @@ target triple = "wasm32-unknown-unknown"
|
||||
; CHECK-LABEL: test:
|
||||
; CHECK-NEXT: call .Lbitcast@FUNCTION{{$}}
|
||||
; CHECK-NEXT: call .Lbitcast.1@FUNCTION{{$}}
|
||||
; CHECK-NEXT: i32.const $push[[L0:[0-9]*]]=, 0
|
||||
; CHECK-NEXT: i32.const $push[[L0:[0-9]+]]=, 0
|
||||
; CHECK-NEXT: call .Lbitcast.2@FUNCTION, $pop[[L0]]{{$}}
|
||||
; CHECK-NEXT: i32.call $drop=, .Lbitcast.3@FUNCTION{{$}}
|
||||
; CHECK-NEXT: call foo2@FUNCTION{{$}}
|
||||
|
26
test/CodeGen/WebAssembly/unsupported-function-bitcasts.ll
Normal file
26
test/CodeGen/WebAssembly/unsupported-function-bitcasts.ll
Normal file
@ -0,0 +1,26 @@
|
||||
; RUN: llc < %s -asm-verbose=false | FileCheck %s
|
||||
|
||||
; Test that function pointer casts that require conversions are not converted
|
||||
; to wrappers. In theory some conversions could be supported, but currently no
|
||||
; conversions are implemented.
|
||||
|
||||
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
|
||||
target triple = "wasm32-unknown-unknown"
|
||||
|
||||
; CHECK-LABEL: test:
|
||||
; CHECK-NEXT: i32.const $push[[L0:[0-9]+]]=, 0{{$}}
|
||||
; CHECK-NEXT: call has_i64_arg@FUNCTION, $pop[[L0]]{{$}}
|
||||
; CHECK-NEXT: i32.call $drop=, has_i64_ret@FUNCTION{{$}}
|
||||
; CHECK-NEXT: .endfunc
|
||||
|
||||
; CHECK-NOT: .Lbitcast
|
||||
|
||||
declare void @has_i64_arg(i64)
|
||||
declare i64 @has_i64_ret()
|
||||
|
||||
define void @test() {
|
||||
entry:
|
||||
call void bitcast (void (i64)* @has_i64_arg to void (i32)*)(i32 0)
|
||||
%t = call i32 bitcast (i64 ()* @has_i64_ret to i32 ()*)()
|
||||
ret void
|
||||
}
|
Loading…
Reference in New Issue
Block a user