1 //=== WebAssemblyLowerRefTypesIntPtrConv.cpp -
2 // Lower IntToPtr and PtrToInt on Reference Types ---===//
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8 //===----------------------------------------------------------------------===//
11 /// Lowers IntToPtr and PtrToInt instructions on reference types to
12 /// Trap instructions since they have been allowed to operate
13 /// on non-integral pointers.
15 //===----------------------------------------------------------------------===//
17 #include "WebAssembly.h"
18 #include "WebAssemblySubtarget.h"
19 #include "llvm/IR/InstIterator.h"
20 #include "llvm/Pass.h"
24 #define DEBUG_TYPE "wasm-lower-reftypes-intptr-conv"
27 class WebAssemblyLowerRefTypesIntPtrConv final
: public FunctionPass
{
28 StringRef
getPassName() const override
{
29 return "WebAssembly Lower RefTypes Int-Ptr Conversions";
32 static bool isRefType(Type
*T
);
34 bool runOnFunction(Function
&MF
) override
;
37 static char ID
; // Pass identification
38 WebAssemblyLowerRefTypesIntPtrConv() : FunctionPass(ID
) {}
40 } // end anonymous namespace
42 char WebAssemblyLowerRefTypesIntPtrConv::ID
= 0;
43 INITIALIZE_PASS(WebAssemblyLowerRefTypesIntPtrConv
, DEBUG_TYPE
,
44 "WebAssembly Lower RefTypes Int-Ptr Conversions", false, false)
46 FunctionPass
*llvm::createWebAssemblyLowerRefTypesIntPtrConv() {
47 return new WebAssemblyLowerRefTypesIntPtrConv();
50 bool WebAssemblyLowerRefTypesIntPtrConv::isRefType(Type
*T
) {
51 return WebAssemblyTargetLowering::isFuncrefType(T
) ||
52 WebAssemblyTargetLowering::isExternrefType(T
);
55 bool WebAssemblyLowerRefTypesIntPtrConv::runOnFunction(Function
&F
) {
56 LLVM_DEBUG(dbgs() << "********** Lower RefTypes IntPtr Convs **********\n"
57 "********** Function: "
58 << F
.getName() << '\n');
60 // This function will check for uses of ptrtoint and inttoptr on reference
61 // types and replace them with a trap instruction.
63 // We replace the instruction by a trap instruction
64 // and its uses by null in the case of inttoptr and 0 in the
66 std::set
<Instruction
*> worklist
;
68 for (inst_iterator I
= inst_begin(F
), E
= inst_end(F
); I
!= E
; ++I
) {
69 PtrToIntInst
*PTI
= dyn_cast
<PtrToIntInst
>(&*I
);
70 IntToPtrInst
*ITP
= dyn_cast
<IntToPtrInst
>(&*I
);
71 if (!(PTI
&& isRefType(PTI
->getPointerOperand()->getType())) &&
72 !(ITP
&& isRefType(ITP
->getDestTy())))
75 UndefValue
*U
= UndefValue::get(I
->getType());
76 I
->replaceAllUsesWith(U
);
78 Function
*TrapIntrin
=
79 Intrinsic::getDeclaration(F
.getParent(), Intrinsic::debugtrap
);
80 CallInst::Create(TrapIntrin
, {}, "", &*I
);
85 // erase each instruction replaced by trap
86 for (Instruction
*I
: worklist
)
89 return !worklist
.empty();