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