1 //=== WebAssemblyLowerRefTypesIntPtrConv.cpp - 2 // Lower IntToPtr and PtrToInt on Reference Types ---===// 3 // 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 7 // 8 //===----------------------------------------------------------------------===// 9 /// 10 /// \file 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. 14 /// 15 //===----------------------------------------------------------------------===// 16 17 #include "Utils/WebAssemblyTypeUtilities.h" 18 #include "WebAssembly.h" 19 #include "WebAssemblySubtarget.h" 20 #include "llvm/IR/InstIterator.h" 21 #include "llvm/Pass.h" 22 23 using namespace llvm; 24 25 #define DEBUG_TYPE "wasm-lower-reftypes-intptr-conv" 26 27 namespace { 28 class WebAssemblyLowerRefTypesIntPtrConv final : public FunctionPass { 29 StringRef getPassName() const override { 30 return "WebAssembly Lower RefTypes Int-Ptr Conversions"; 31 } 32 33 bool runOnFunction(Function &MF) override; 34 35 public: 36 static char ID; // Pass identification 37 WebAssemblyLowerRefTypesIntPtrConv() : FunctionPass(ID) {} 38 }; 39 } // end anonymous namespace 40 41 char WebAssemblyLowerRefTypesIntPtrConv::ID = 0; 42 INITIALIZE_PASS(WebAssemblyLowerRefTypesIntPtrConv, DEBUG_TYPE, 43 "WebAssembly Lower RefTypes Int-Ptr Conversions", false, false) 44 45 FunctionPass *llvm::createWebAssemblyLowerRefTypesIntPtrConv() { 46 return new WebAssemblyLowerRefTypesIntPtrConv(); 47 } 48 49 bool WebAssemblyLowerRefTypesIntPtrConv::runOnFunction(Function &F) { 50 LLVM_DEBUG(dbgs() << "********** Lower RefTypes IntPtr Convs **********\n" 51 "********** Function: " 52 << F.getName() << '\n'); 53 54 // This function will check for uses of ptrtoint and inttoptr on reference 55 // types and replace them with a trap instruction. 56 // 57 // We replace the instruction by a trap instruction 58 // and its uses by null in the case of inttoptr and 0 in the 59 // case of ptrtoint. 60 std::set<Instruction *> worklist; 61 62 for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) { 63 PtrToIntInst *PTI = dyn_cast<PtrToIntInst>(&*I); 64 IntToPtrInst *ITP = dyn_cast<IntToPtrInst>(&*I); 65 if (!(PTI && WebAssembly::isRefType(PTI->getPointerOperand()->getType())) && 66 !(ITP && WebAssembly::isRefType(ITP->getDestTy()))) 67 continue; 68 69 UndefValue *U = UndefValue::get(I->getType()); 70 I->replaceAllUsesWith(U); 71 72 Function *TrapIntrin = 73 Intrinsic::getDeclaration(F.getParent(), Intrinsic::debugtrap); 74 CallInst::Create(TrapIntrin, {}, "", &*I); 75 76 worklist.insert(&*I); 77 } 78 79 // erase each instruction replaced by trap 80 for (Instruction *I : worklist) 81 I->eraseFromParent(); 82 83 return !worklist.empty(); 84 } 85