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 23using namespace llvm; 24 25#define DEBUG_TYPE "wasm-lower-reftypes-intptr-conv" 26 27namespace { 28class 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 35public: 36 static char ID; // Pass identification 37 WebAssemblyLowerRefTypesIntPtrConv() : FunctionPass(ID) {} 38}; 39} // end anonymous namespace 40 41char WebAssemblyLowerRefTypesIntPtrConv::ID = 0; 42INITIALIZE_PASS(WebAssemblyLowerRefTypesIntPtrConv, DEBUG_TYPE, 43 "WebAssembly Lower RefTypes Int-Ptr Conversions", false, false) 44 45FunctionPass *llvm::createWebAssemblyLowerRefTypesIntPtrConv() { 46 return new WebAssemblyLowerRefTypesIntPtrConv(); 47} 48 49bool 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