AutoUpgrade.cpp revision de49f360ec4780acb382a3ae923d1716fdb0dc03
16994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth//===-- AutoUpgrade.cpp - Implement auto-upgrade helper functions ---------===// 26994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth// 36994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth// The LLVM Compiler Infrastructure 46994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth// 54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source 64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details. 76994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth// 86994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth//===----------------------------------------------------------------------===// 96994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth// 106994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth// This file implements the auto-upgrade helper functions 116994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth// 126994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth//===----------------------------------------------------------------------===// 136994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 146994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth#include "llvm/AutoUpgrade.h" 15d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson#include "llvm/Constants.h" 166994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth#include "llvm/Function.h" 17f81b57694b3c34a79b1464ffd21e6768c8d22662Owen Anderson#include "llvm/LLVMContext.h" 186994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth#include "llvm/Module.h" 19e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel#include "llvm/IntrinsicInst.h" 2058d74910c6b82e622ecbb57d6644d48fec5a5c0fChris Lattner#include "llvm/ADT/SmallVector.h" 21bb6eabf4f5b518a333ab4cedce910962ff935e3aGabor Greif#include "llvm/Support/CallSite.h" 22c25e7581b9b8088910da31702d4ca21c4734c6d7Torok Edwin#include "llvm/Support/ErrorHandling.h" 236d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher#include "llvm/Support/IRBuilder.h" 24ae9f3a3b7c915f725aef5a7250e88eaeddda03c6Anton Korobeynikov#include <cstring> 256994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruthusing namespace llvm; 266994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 276994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 28f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Chengstatic bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) { 296994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth assert(F && "Illegal to upgrade a non-existent Function."); 306994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 316994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // Get the Function's name. 326994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth const std::string& Name = F->getName(); 336994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 346994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // Convenience 356994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth const FunctionType *FTy = F->getFunctionType(); 366994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 376994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // Quickly eliminate it, if it's not a candidate. 386994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth if (Name.length() <= 8 || Name[0] != 'l' || Name[1] != 'l' || 396994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth Name[2] != 'v' || Name[3] != 'm' || Name[4] != '.') 40f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng return false; 416994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 426994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth Module *M = F->getParent(); 436994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth switch (Name[5]) { 446994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth default: break; 4528873106309db515d58889a4c4fa3e0a92d1b60eMon P Wang case 'a': 46e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang // This upgrades the llvm.atomic.lcs, llvm.atomic.las, llvm.atomic.lss, 47e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang // and atomics with default address spaces to their new names to their new 48e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang // function name (e.g. llvm.atomic.add.i32 => llvm.atomic.add.i32.p0i32) 49e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang if (Name.compare(5,7,"atomic.",7) == 0) { 5028873106309db515d58889a4c4fa3e0a92d1b60eMon P Wang if (Name.compare(12,3,"lcs",3) == 0) { 5128873106309db515d58889a4c4fa3e0a92d1b60eMon P Wang std::string::size_type delim = Name.find('.',12); 52e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang F->setName("llvm.atomic.cmp.swap" + Name.substr(delim) + 53e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang ".p0" + Name.substr(delim+1)); 5428873106309db515d58889a4c4fa3e0a92d1b60eMon P Wang NewFn = F; 5528873106309db515d58889a4c4fa3e0a92d1b60eMon P Wang return true; 5628873106309db515d58889a4c4fa3e0a92d1b60eMon P Wang } 5728873106309db515d58889a4c4fa3e0a92d1b60eMon P Wang else if (Name.compare(12,3,"las",3) == 0) { 5828873106309db515d58889a4c4fa3e0a92d1b60eMon P Wang std::string::size_type delim = Name.find('.',12); 59e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang F->setName("llvm.atomic.load.add"+Name.substr(delim) 60e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang + ".p0" + Name.substr(delim+1)); 6128873106309db515d58889a4c4fa3e0a92d1b60eMon P Wang NewFn = F; 6228873106309db515d58889a4c4fa3e0a92d1b60eMon P Wang return true; 6328873106309db515d58889a4c4fa3e0a92d1b60eMon P Wang } 6428873106309db515d58889a4c4fa3e0a92d1b60eMon P Wang else if (Name.compare(12,3,"lss",3) == 0) { 6528873106309db515d58889a4c4fa3e0a92d1b60eMon P Wang std::string::size_type delim = Name.find('.',12); 66e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang F->setName("llvm.atomic.load.sub"+Name.substr(delim) 67e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang + ".p0" + Name.substr(delim+1)); 68e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang NewFn = F; 69e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang return true; 70e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang } 71e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang else if (Name.rfind(".p") == std::string::npos) { 72e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang // We don't have an address space qualifier so this has be upgraded 73e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang // to the new name. Copy the type name at the end of the intrinsic 74e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang // and add to it 75e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang std::string::size_type delim = Name.find_last_of('.'); 76e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang assert(delim != std::string::npos && "can not find type"); 77e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang F->setName(Name + ".p0" + Name.substr(delim+1)); 7828873106309db515d58889a4c4fa3e0a92d1b60eMon P Wang NewFn = F; 7928873106309db515d58889a4c4fa3e0a92d1b60eMon P Wang return true; 8028873106309db515d58889a4c4fa3e0a92d1b60eMon P Wang } 81b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson } else if (Name.compare(5, 9, "arm.neon.", 9) == 0) { 8204d6c289ab28114af5471c4dc38cbf7b7127d3c3Bob Wilson if (((Name.compare(14, 5, "vmovl", 5) == 0 || 8304d6c289ab28114af5471c4dc38cbf7b7127d3c3Bob Wilson Name.compare(14, 5, "vaddl", 5) == 0 || 84eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson Name.compare(14, 5, "vsubl", 5) == 0 || 85eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson Name.compare(14, 5, "vaddw", 5) == 0 || 86eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson Name.compare(14, 5, "vsubw", 5) == 0 || 87eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson Name.compare(14, 5, "vmull", 5) == 0 || 88d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson Name.compare(14, 5, "vmlal", 5) == 0 || 89eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson Name.compare(14, 5, "vmlsl", 5) == 0 || 90eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson Name.compare(14, 5, "vabdl", 5) == 0 || 91eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson Name.compare(14, 5, "vabal", 5) == 0) && 92d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson (Name.compare(19, 2, "s.", 2) == 0 || 93d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson Name.compare(19, 2, "u.", 2) == 0)) || 94d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson 95eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson (Name.compare(14, 4, "vaba", 4) == 0 && 96eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson (Name.compare(18, 2, "s.", 2) == 0 || 97eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson Name.compare(18, 2, "u.", 2) == 0)) || 98eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson 99973a074345add36c046c0f0bfea0156a532ab479Bob Wilson (Name.compare(14, 6, "vmovn.", 6) == 0)) { 10004d6c289ab28114af5471c4dc38cbf7b7127d3c3Bob Wilson 101b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson // Calls to these are transformed into IR without intrinsics. 102b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson NewFn = 0; 103b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson return true; 104b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson } 1057a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson // Old versions of NEON ld/st intrinsics are missing alignment arguments. 1067a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson bool isVLd = (Name.compare(14, 3, "vld", 3) == 0); 1077a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson bool isVSt = (Name.compare(14, 3, "vst", 3) == 0); 1087a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson if (isVLd || isVSt) { 1097a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson unsigned NumVecs = Name.at(17) - '0'; 1107a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson if (NumVecs == 0 || NumVecs > 4) 1117a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson return false; 1127a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson bool isLaneOp = (Name.compare(18, 5, "lane.", 5) == 0); 1137a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson if (!isLaneOp && Name.at(18) != '.') 1147a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson return false; 1157a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson unsigned ExpectedArgs = 2; // for the address and alignment 1167a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson if (isVSt || isLaneOp) 1177a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson ExpectedArgs += NumVecs; 1187a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson if (isLaneOp) 1197a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson ExpectedArgs += 1; // for the lane number 1207a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson unsigned NumP = FTy->getNumParams(); 1217a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson if (NumP != ExpectedArgs - 1) 1227a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson return false; 1237a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson 1247a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson // Change the name of the old (bad) intrinsic, because 1257a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson // its type is incorrect, but we cannot overload that name. 1267a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson F->setName(""); 1277a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson 1287a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson // One argument is missing: add the alignment argument. 1297a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson std::vector<const Type*> NewParams; 1307a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson for (unsigned p = 0; p < NumP; ++p) 1317a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson NewParams.push_back(FTy->getParamType(p)); 1327a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson NewParams.push_back(Type::getInt32Ty(F->getContext())); 1337a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson FunctionType *NewFTy = FunctionType::get(FTy->getReturnType(), 1347a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson NewParams, false); 1357a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson NewFn = cast<Function>(M->getOrInsertFunction(Name, NewFTy)); 1367a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson return true; 1377a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson } 13828873106309db515d58889a4c4fa3e0a92d1b60eMon P Wang } 13928873106309db515d58889a4c4fa3e0a92d1b60eMon P Wang break; 1406994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth case 'b': 1416994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // This upgrades the name of the llvm.bswap intrinsic function to only use 1426994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // a single type name for overloading. We only care about the old format 1436994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // 'llvm.bswap.i*.i*', so check for 'bswap.' and then for there being 1446994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // a '.' after 'bswap.' 1456994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth if (Name.compare(5,6,"bswap.",6) == 0) { 1466994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth std::string::size_type delim = Name.find('.',11); 1476994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 1486994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth if (delim != std::string::npos) { 1496994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // Construct the new name as 'llvm.bswap' + '.i*' 1506994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth F->setName(Name.substr(0,10)+Name.substr(delim)); 151f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng NewFn = F; 152f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng return true; 1536994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth } 1546994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth } 1556994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth break; 1566994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 1576994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth case 'c': 1586994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // We only want to fix the 'llvm.ct*' intrinsics which do not have the 1596994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // correct return type, so we check for the name, and then check if the 1606994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // return type does not match the parameter type. 1616994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth if ( (Name.compare(5,5,"ctpop",5) == 0 || 1626994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth Name.compare(5,4,"ctlz",4) == 0 || 1636994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth Name.compare(5,4,"cttz",4) == 0) && 1646994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth FTy->getReturnType() != FTy->getParamType(0)) { 1656994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // We first need to change the name of the old (bad) intrinsic, because 1666994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // its type is incorrect, but we cannot overload that name. We 1676994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // arbitrarily unique it here allowing us to construct a correctly named 1686994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // and typed function below. 1696994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth F->setName(""); 1706994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 1716994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // Now construct the new intrinsic with the correct name and type. We 1726994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // leave the old function around in order to query its type, whatever it 1736994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // may be, and correctly convert up to the new type. 174f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng NewFn = cast<Function>(M->getOrInsertFunction(Name, 175f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng FTy->getParamType(0), 176f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng FTy->getParamType(0), 177f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng (Type *)0)); 178f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng return true; 1796994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth } 1806994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth break; 1816994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 182b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands case 'e': 183b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands // The old llvm.eh.selector.i32 is equivalent to the new llvm.eh.selector. 184b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands if (Name.compare("llvm.eh.selector.i32") == 0) { 185b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands F->setName("llvm.eh.selector"); 186b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands NewFn = F; 187b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands return true; 188b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands } 189b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands // The old llvm.eh.typeid.for.i32 is equivalent to llvm.eh.typeid.for. 190b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands if (Name.compare("llvm.eh.typeid.for.i32") == 0) { 191b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands F->setName("llvm.eh.typeid.for"); 192b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands NewFn = F; 193b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands return true; 194b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands } 195b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands // Convert the old llvm.eh.selector.i64 to a call to llvm.eh.selector. 196b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands if (Name.compare("llvm.eh.selector.i64") == 0) { 197b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands NewFn = Intrinsic::getDeclaration(M, Intrinsic::eh_selector); 198b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands return true; 199b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands } 200b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands // Convert the old llvm.eh.typeid.for.i64 to a call to llvm.eh.typeid.for. 201b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands if (Name.compare("llvm.eh.typeid.for.i64") == 0) { 202b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands NewFn = Intrinsic::getDeclaration(M, Intrinsic::eh_typeid_for); 203b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands return true; 204b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands } 205b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands break; 206b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands 20720adc9dc4650313f017b27d9818eb2176238113dMon P Wang case 'm': { 20820adc9dc4650313f017b27d9818eb2176238113dMon P Wang // This upgrades the llvm.memcpy, llvm.memmove, and llvm.memset to the 20920adc9dc4650313f017b27d9818eb2176238113dMon P Wang // new format that allows overloading the pointer for different address 21020adc9dc4650313f017b27d9818eb2176238113dMon P Wang // space (e.g., llvm.memcpy.i16 => llvm.memcpy.p0i8.p0i8.i16) 21120adc9dc4650313f017b27d9818eb2176238113dMon P Wang const char* NewFnName = NULL; 21220adc9dc4650313f017b27d9818eb2176238113dMon P Wang if (Name.compare(5,8,"memcpy.i",8) == 0) { 21320adc9dc4650313f017b27d9818eb2176238113dMon P Wang if (Name[13] == '8') 21420adc9dc4650313f017b27d9818eb2176238113dMon P Wang NewFnName = "llvm.memcpy.p0i8.p0i8.i8"; 21520adc9dc4650313f017b27d9818eb2176238113dMon P Wang else if (Name.compare(13,2,"16") == 0) 21620adc9dc4650313f017b27d9818eb2176238113dMon P Wang NewFnName = "llvm.memcpy.p0i8.p0i8.i16"; 21720adc9dc4650313f017b27d9818eb2176238113dMon P Wang else if (Name.compare(13,2,"32") == 0) 21820adc9dc4650313f017b27d9818eb2176238113dMon P Wang NewFnName = "llvm.memcpy.p0i8.p0i8.i32"; 21920adc9dc4650313f017b27d9818eb2176238113dMon P Wang else if (Name.compare(13,2,"64") == 0) 22020adc9dc4650313f017b27d9818eb2176238113dMon P Wang NewFnName = "llvm.memcpy.p0i8.p0i8.i64"; 22120adc9dc4650313f017b27d9818eb2176238113dMon P Wang } else if (Name.compare(5,9,"memmove.i",9) == 0) { 22220adc9dc4650313f017b27d9818eb2176238113dMon P Wang if (Name[14] == '8') 22320adc9dc4650313f017b27d9818eb2176238113dMon P Wang NewFnName = "llvm.memmove.p0i8.p0i8.i8"; 22420adc9dc4650313f017b27d9818eb2176238113dMon P Wang else if (Name.compare(14,2,"16") == 0) 22520adc9dc4650313f017b27d9818eb2176238113dMon P Wang NewFnName = "llvm.memmove.p0i8.p0i8.i16"; 22620adc9dc4650313f017b27d9818eb2176238113dMon P Wang else if (Name.compare(14,2,"32") == 0) 22720adc9dc4650313f017b27d9818eb2176238113dMon P Wang NewFnName = "llvm.memmove.p0i8.p0i8.i32"; 22820adc9dc4650313f017b27d9818eb2176238113dMon P Wang else if (Name.compare(14,2,"64") == 0) 22920adc9dc4650313f017b27d9818eb2176238113dMon P Wang NewFnName = "llvm.memmove.p0i8.p0i8.i64"; 23020adc9dc4650313f017b27d9818eb2176238113dMon P Wang } 23120adc9dc4650313f017b27d9818eb2176238113dMon P Wang else if (Name.compare(5,8,"memset.i",8) == 0) { 23220adc9dc4650313f017b27d9818eb2176238113dMon P Wang if (Name[13] == '8') 23320adc9dc4650313f017b27d9818eb2176238113dMon P Wang NewFnName = "llvm.memset.p0i8.i8"; 23420adc9dc4650313f017b27d9818eb2176238113dMon P Wang else if (Name.compare(13,2,"16") == 0) 23520adc9dc4650313f017b27d9818eb2176238113dMon P Wang NewFnName = "llvm.memset.p0i8.i16"; 23620adc9dc4650313f017b27d9818eb2176238113dMon P Wang else if (Name.compare(13,2,"32") == 0) 23720adc9dc4650313f017b27d9818eb2176238113dMon P Wang NewFnName = "llvm.memset.p0i8.i32"; 23820adc9dc4650313f017b27d9818eb2176238113dMon P Wang else if (Name.compare(13,2,"64") == 0) 23920adc9dc4650313f017b27d9818eb2176238113dMon P Wang NewFnName = "llvm.memset.p0i8.i64"; 24020adc9dc4650313f017b27d9818eb2176238113dMon P Wang } 24120adc9dc4650313f017b27d9818eb2176238113dMon P Wang if (NewFnName) { 24220adc9dc4650313f017b27d9818eb2176238113dMon P Wang NewFn = cast<Function>(M->getOrInsertFunction(NewFnName, 24320adc9dc4650313f017b27d9818eb2176238113dMon P Wang FTy->getReturnType(), 24420adc9dc4650313f017b27d9818eb2176238113dMon P Wang FTy->getParamType(0), 24520adc9dc4650313f017b27d9818eb2176238113dMon P Wang FTy->getParamType(1), 24620adc9dc4650313f017b27d9818eb2176238113dMon P Wang FTy->getParamType(2), 24720adc9dc4650313f017b27d9818eb2176238113dMon P Wang FTy->getParamType(3), 24820adc9dc4650313f017b27d9818eb2176238113dMon P Wang Type::getInt1Ty(F->getContext()), 24920adc9dc4650313f017b27d9818eb2176238113dMon P Wang (Type *)0)); 25020adc9dc4650313f017b27d9818eb2176238113dMon P Wang return true; 25120adc9dc4650313f017b27d9818eb2176238113dMon P Wang } 25220adc9dc4650313f017b27d9818eb2176238113dMon P Wang break; 25320adc9dc4650313f017b27d9818eb2176238113dMon P Wang } 2546994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth case 'p': 2556994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // This upgrades the llvm.part.select overloaded intrinsic names to only 2566994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // use one type specifier in the name. We only care about the old format 2576994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // 'llvm.part.select.i*.i*', and solve as above with bswap. 2586994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth if (Name.compare(5,12,"part.select.",12) == 0) { 2596994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth std::string::size_type delim = Name.find('.',17); 2606994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 2616994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth if (delim != std::string::npos) { 2626994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // Construct a new name as 'llvm.part.select' + '.i*' 2636994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth F->setName(Name.substr(0,16)+Name.substr(delim)); 264f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng NewFn = F; 265f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng return true; 2666994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth } 2676994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth break; 2686994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth } 2696994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 2706994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // This upgrades the llvm.part.set intrinsics similarly as above, however 2716994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // we care about 'llvm.part.set.i*.i*.i*', but only the first two types 2726994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // must match. There is an additional type specifier after these two 2736994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // matching types that we must retain when upgrading. Thus, we require 2746994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // finding 2 periods, not just one, after the intrinsic name. 2756994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth if (Name.compare(5,9,"part.set.",9) == 0) { 2766994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth std::string::size_type delim = Name.find('.',14); 2776994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 2786994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth if (delim != std::string::npos && 2796994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth Name.find('.',delim+1) != std::string::npos) { 2806994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // Construct a new name as 'llvm.part.select' + '.i*.i*' 2816994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth F->setName(Name.substr(0,13)+Name.substr(delim)); 282f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng NewFn = F; 283f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng return true; 2846994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth } 2856994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth break; 2866994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth } 2876994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 2886994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth break; 289d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson case 'x': 290d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson // This fixes all MMX shift intrinsic instructions to take a 291d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson // v1i64 instead of a v2i32 as the second parameter. 292d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson if (Name.compare(5,10,"x86.mmx.ps",10) == 0 && 293d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson (Name.compare(13,4,"psll", 4) == 0 || 294d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson Name.compare(13,4,"psra", 4) == 0 || 29522b942aa4df824adbd3f6eaede53abe451f616e9Evan Cheng Name.compare(13,4,"psrl", 4) == 0) && Name[17] != 'i') { 296d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson 297f81b57694b3c34a79b1464ffd21e6768c8d22662Owen Anderson const llvm::Type *VT = 2981d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson VectorType::get(IntegerType::get(FTy->getContext(), 64), 1); 299d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson 300d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson // We don't have to do anything if the parameter already has 301d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson // the correct type. 302d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson if (FTy->getParamType(1) == VT) 303d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson break; 304d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson 305d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson // We first need to change the name of the old (bad) intrinsic, because 306d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson // its type is incorrect, but we cannot overload that name. We 307d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson // arbitrarily unique it here allowing us to construct a correctly named 308d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson // and typed function below. 309d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson F->setName(""); 310d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson 311d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson assert(FTy->getNumParams() == 2 && "MMX shift intrinsics take 2 args!"); 312d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson 313d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson // Now construct the new intrinsic with the correct name and type. We 314d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson // leave the old function around in order to query its type, whatever it 315d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson // may be, and correctly convert up to the new type. 316f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng NewFn = cast<Function>(M->getOrInsertFunction(Name, 317f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng FTy->getReturnType(), 318f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng FTy->getParamType(0), 319f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng VT, 320f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng (Type *)0)); 321f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng return true; 3224797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng } else if (Name.compare(5,17,"x86.sse2.loadh.pd",17) == 0 || 3234797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng Name.compare(5,17,"x86.sse2.loadl.pd",17) == 0 || 324e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng Name.compare(5,16,"x86.sse2.movl.dq",16) == 0 || 325e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng Name.compare(5,15,"x86.sse2.movs.d",15) == 0 || 326e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng Name.compare(5,16,"x86.sse2.shuf.pd",16) == 0 || 327e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng Name.compare(5,18,"x86.sse2.unpckh.pd",18) == 0 || 328a31593901de573813d1d8e7884a152011641a713Evan Cheng Name.compare(5,18,"x86.sse2.unpckl.pd",18) == 0 || 329a31593901de573813d1d8e7884a152011641a713Evan Cheng Name.compare(5,20,"x86.sse2.punpckh.qdq",20) == 0 || 330a31593901de573813d1d8e7884a152011641a713Evan Cheng Name.compare(5,20,"x86.sse2.punpckl.qdq",20) == 0) { 3314797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng // Calls to these intrinsics are transformed into ShuffleVector's. 332f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng NewFn = 0; 333f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng return true; 3348258d0b4bfd5fe40c29fa19e24c23ba3ac157e23Eric Christopher } else if (Name.compare(5, 16, "x86.sse41.pmulld", 16) == 0) { 3358258d0b4bfd5fe40c29fa19e24c23ba3ac157e23Eric Christopher // Calls to these intrinsics are transformed into vector multiplies. 3368258d0b4bfd5fe40c29fa19e24c23ba3ac157e23Eric Christopher NewFn = 0; 3378258d0b4bfd5fe40c29fa19e24c23ba3ac157e23Eric Christopher return true; 3386d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher } else if (Name.compare(5, 18, "x86.ssse3.palign.r", 18) == 0 || 3396d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Name.compare(5, 22, "x86.ssse3.palign.r.128", 22) == 0) { 3406d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // Calls to these intrinsics are transformed into vector shuffles, shifts, 3416d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // or 0. 3426d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher NewFn = 0; 3436d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher return true; 344d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson } 345f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng 346d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson break; 3476994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth } 3486994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 3496994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // This may not belong here. This function is effectively being overloaded 3506994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // to both detect an intrinsic which needs upgrading, and to provide the 3516994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // upgraded form of the intrinsic. We should perhaps have two separate 3526994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // functions for this. 353f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng return false; 3546994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth} 3556994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 356f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Chengbool llvm::UpgradeIntrinsicFunction(Function *F, Function *&NewFn) { 357f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng NewFn = 0; 358f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng bool Upgraded = UpgradeIntrinsicFunction1(F, NewFn); 359a3355ffb3d30d19d226bbb75707991c60f236e37Duncan Sands 360a3355ffb3d30d19d226bbb75707991c60f236e37Duncan Sands // Upgrade intrinsic attributes. This does not change the function. 361f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng if (NewFn) 362f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng F = NewFn; 36349de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen if (unsigned id = F->getIntrinsicID()) 3640598866c052147c31b808391f58434ce3dbfb838Devang Patel F->setAttributes(Intrinsic::getAttributes((Intrinsic::ID)id)); 365a3355ffb3d30d19d226bbb75707991c60f236e37Duncan Sands return Upgraded; 366a3355ffb3d30d19d226bbb75707991c60f236e37Duncan Sands} 367a3355ffb3d30d19d226bbb75707991c60f236e37Duncan Sands 368de49f360ec4780acb382a3ae923d1716fdb0dc03Bill Wendlingbool llvm::UpgradeGlobalVariable(GlobalVariable *GV) { 369de49f360ec4780acb382a3ae923d1716fdb0dc03Bill Wendling const std::string &Name = GV->getName(); 370de49f360ec4780acb382a3ae923d1716fdb0dc03Bill Wendling 371de49f360ec4780acb382a3ae923d1716fdb0dc03Bill Wendling // We are only upgrading one symbol here. If we upgrade more, we will want to 372de49f360ec4780acb382a3ae923d1716fdb0dc03Bill Wendling // perform some sort of short-circuiting like in the 373de49f360ec4780acb382a3ae923d1716fdb0dc03Bill Wendling // "UpgradeIntrinsicFunction1" function. 374de49f360ec4780acb382a3ae923d1716fdb0dc03Bill Wendling if (Name == ".llvm.eh.catch.all.value") { 375de49f360ec4780acb382a3ae923d1716fdb0dc03Bill Wendling GV->setName("llvm.eh.catch.all.value"); 376de49f360ec4780acb382a3ae923d1716fdb0dc03Bill Wendling return true; 377de49f360ec4780acb382a3ae923d1716fdb0dc03Bill Wendling } 378de49f360ec4780acb382a3ae923d1716fdb0dc03Bill Wendling 379de49f360ec4780acb382a3ae923d1716fdb0dc03Bill Wendling return false; 380de49f360ec4780acb382a3ae923d1716fdb0dc03Bill Wendling} 381de49f360ec4780acb382a3ae923d1716fdb0dc03Bill Wendling 382d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson/// ExtendNEONArgs - For NEON "long" and "wide" operations, where the results 383d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson/// have vector elements twice as big as one or both source operands, do the 384d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson/// sign- or zero-extension that used to be handled by intrinsics. The 385d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson/// extended values are returned via V0 and V1. 386d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilsonstatic void ExtendNEONArgs(CallInst *CI, Value *Arg0, Value *Arg1, 387d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson Value *&V0, Value *&V1) { 388d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson Function *F = CI->getCalledFunction(); 389d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson const std::string& Name = F->getName(); 390d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson bool isLong = (Name.at(18) == 'l'); 391d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson bool isSigned = (Name.at(19) == 's'); 392d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson 393d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson if (isSigned) { 394d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson if (isLong) 395d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson V0 = new SExtInst(Arg0, CI->getType(), "", CI); 396d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson else 397d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson V0 = Arg0; 398d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson V1 = new SExtInst(Arg1, CI->getType(), "", CI); 399d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson } else { 400d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson if (isLong) 401d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson V0 = new ZExtInst(Arg0, CI->getType(), "", CI); 402d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson else 403d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson V0 = Arg0; 404d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson V1 = new ZExtInst(Arg1, CI->getType(), "", CI); 405d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson } 406d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson} 407d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson 408eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson/// CallVABD - As part of expanding a call to one of the old NEON vabdl, vaba, 409eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson/// or vabal intrinsics, construct a call to a vabd intrinsic. Examine the 410eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson/// name of the old intrinsic to determine whether to use a signed or unsigned 411eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson/// vabd intrinsic. Get the type from the old call instruction, adjusted for 412eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson/// half-size vector elements if the old intrinsic was vabdl or vabal. 413eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilsonstatic Instruction *CallVABD(CallInst *CI, Value *Arg0, Value *Arg1) { 414eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson Function *F = CI->getCalledFunction(); 415eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson const std::string& Name = F->getName(); 416eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson bool isLong = (Name.at(18) == 'l'); 417eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson bool isSigned = (Name.at(isLong ? 19 : 18) == 's'); 418eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson 419eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson Intrinsic::ID intID; 420eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson if (isSigned) 421eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson intID = Intrinsic::arm_neon_vabds; 422eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson else 423eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson intID = Intrinsic::arm_neon_vabdu; 424eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson 425eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson const Type *Ty = CI->getType(); 426eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson if (isLong) 427eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson Ty = VectorType::getTruncatedElementVectorType(cast<const VectorType>(Ty)); 428eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson 429eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson Function *VABD = Intrinsic::getDeclaration(F->getParent(), intID, &Ty, 1); 430eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson Value *Operands[2]; 431eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson Operands[0] = Arg0; 432eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson Operands[1] = Arg1; 433eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson return CallInst::Create(VABD, Operands, Operands+2, 434eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson "upgraded."+CI->getName(), CI); 435eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson} 436eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson 4376994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth// UpgradeIntrinsicCall - Upgrade a call to an old intrinsic to be a call the 4386994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth// upgraded intrinsic. All argument and return casting must be provided in 4396994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth// order to seamlessly integrate with existing context. 4406994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruthvoid llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { 4416994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth Function *F = CI->getCalledFunction(); 4421d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson LLVMContext &C = CI->getContext(); 443bb6eabf4f5b518a333ab4cedce910962ff935e3aGabor Greif ImmutableCallSite CS(CI); 444bb6eabf4f5b518a333ab4cedce910962ff935e3aGabor Greif 4456994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth assert(F && "CallInst has no function associated with it."); 446f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng 447f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng if (!NewFn) { 448b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson // Get the Function's name. 449b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson const std::string& Name = F->getName(); 450b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson 451b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson // Upgrade ARM NEON intrinsics. 452b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson if (Name.compare(5, 9, "arm.neon.", 9) == 0) { 453b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson Instruction *NewI; 454d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson Value *V0, *V1; 455b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson if (Name.compare(14, 7, "vmovls.", 7) == 0) { 456b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson NewI = new SExtInst(CI->getArgOperand(0), CI->getType(), 457b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson "upgraded." + CI->getName(), CI); 458b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson } else if (Name.compare(14, 7, "vmovlu.", 7) == 0) { 459b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson NewI = new ZExtInst(CI->getArgOperand(0), CI->getType(), 460b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson "upgraded." + CI->getName(), CI); 461d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson } else if (Name.compare(14, 4, "vadd", 4) == 0) { 462d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson ExtendNEONArgs(CI, CI->getArgOperand(0), CI->getArgOperand(1), V0, V1); 463d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson NewI = BinaryOperator::CreateAdd(V0, V1, "upgraded."+CI->getName(), CI); 464d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson } else if (Name.compare(14, 4, "vsub", 4) == 0) { 465d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson ExtendNEONArgs(CI, CI->getArgOperand(0), CI->getArgOperand(1), V0, V1); 466d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson NewI = BinaryOperator::CreateSub(V0, V1,"upgraded."+CI->getName(),CI); 467d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson } else if (Name.compare(14, 4, "vmul", 4) == 0) { 468d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson ExtendNEONArgs(CI, CI->getArgOperand(0), CI->getArgOperand(1), V0, V1); 469d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson NewI = BinaryOperator::CreateMul(V0, V1,"upgraded."+CI->getName(),CI); 470d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson } else if (Name.compare(14, 4, "vmla", 4) == 0) { 471d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson ExtendNEONArgs(CI, CI->getArgOperand(1), CI->getArgOperand(2), V0, V1); 472d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson Instruction *MulI = BinaryOperator::CreateMul(V0, V1, "", CI); 473d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson NewI = BinaryOperator::CreateAdd(CI->getArgOperand(0), MulI, 474d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson "upgraded."+CI->getName(), CI); 475d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson } else if (Name.compare(14, 4, "vmls", 4) == 0) { 476d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson ExtendNEONArgs(CI, CI->getArgOperand(1), CI->getArgOperand(2), V0, V1); 477d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson Instruction *MulI = BinaryOperator::CreateMul(V0, V1, "", CI); 478d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson NewI = BinaryOperator::CreateSub(CI->getArgOperand(0), MulI, 479d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson "upgraded."+CI->getName(), CI); 480eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson } else if (Name.compare(14, 4, "vabd", 4) == 0) { 481eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson NewI = CallVABD(CI, CI->getArgOperand(0), CI->getArgOperand(1)); 482eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson NewI = new ZExtInst(NewI, CI->getType(), "upgraded."+CI->getName(), CI); 483eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson } else if (Name.compare(14, 4, "vaba", 4) == 0) { 484eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson NewI = CallVABD(CI, CI->getArgOperand(1), CI->getArgOperand(2)); 485eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson if (Name.at(18) == 'l') 486eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson NewI = new ZExtInst(NewI, CI->getType(), "", CI); 487eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson NewI = BinaryOperator::CreateAdd(CI->getArgOperand(0), NewI, 488eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson "upgraded."+CI->getName(), CI); 489973a074345add36c046c0f0bfea0156a532ab479Bob Wilson } else if (Name.compare(14, 6, "vmovn.", 6) == 0) { 490973a074345add36c046c0f0bfea0156a532ab479Bob Wilson NewI = new TruncInst(CI->getArgOperand(0), CI->getType(), 491973a074345add36c046c0f0bfea0156a532ab479Bob Wilson "upgraded." + CI->getName(), CI); 492b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson } else { 493b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson llvm_unreachable("Unknown arm.neon function for CallInst upgrade."); 494b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson } 495b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson // Replace any uses of the old CallInst. 496b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson if (!CI->use_empty()) 497b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson CI->replaceAllUsesWith(NewI); 498b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson CI->eraseFromParent(); 499b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson return; 500b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson } 501b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson 5024797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng bool isLoadH = false, isLoadL = false, isMovL = false; 503e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng bool isMovSD = false, isShufPD = false; 504e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng bool isUnpckhPD = false, isUnpcklPD = false; 505a31593901de573813d1d8e7884a152011641a713Evan Cheng bool isPunpckhQPD = false, isPunpcklQPD = false; 50603d7651c3652e1f0cc86e79b26585d86818da9cfDaniel Dunbar if (F->getName() == "llvm.x86.sse2.loadh.pd") 5074797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng isLoadH = true; 50803d7651c3652e1f0cc86e79b26585d86818da9cfDaniel Dunbar else if (F->getName() == "llvm.x86.sse2.loadl.pd") 5094797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng isLoadL = true; 51003d7651c3652e1f0cc86e79b26585d86818da9cfDaniel Dunbar else if (F->getName() == "llvm.x86.sse2.movl.dq") 5114797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng isMovL = true; 51203d7651c3652e1f0cc86e79b26585d86818da9cfDaniel Dunbar else if (F->getName() == "llvm.x86.sse2.movs.d") 513e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng isMovSD = true; 51403d7651c3652e1f0cc86e79b26585d86818da9cfDaniel Dunbar else if (F->getName() == "llvm.x86.sse2.shuf.pd") 515e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng isShufPD = true; 51603d7651c3652e1f0cc86e79b26585d86818da9cfDaniel Dunbar else if (F->getName() == "llvm.x86.sse2.unpckh.pd") 517e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng isUnpckhPD = true; 51803d7651c3652e1f0cc86e79b26585d86818da9cfDaniel Dunbar else if (F->getName() == "llvm.x86.sse2.unpckl.pd") 519e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng isUnpcklPD = true; 52003d7651c3652e1f0cc86e79b26585d86818da9cfDaniel Dunbar else if (F->getName() == "llvm.x86.sse2.punpckh.qdq") 521a31593901de573813d1d8e7884a152011641a713Evan Cheng isPunpckhQPD = true; 52203d7651c3652e1f0cc86e79b26585d86818da9cfDaniel Dunbar else if (F->getName() == "llvm.x86.sse2.punpckl.qdq") 523a31593901de573813d1d8e7884a152011641a713Evan Cheng isPunpcklQPD = true; 5244797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng 525e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng if (isLoadH || isLoadL || isMovL || isMovSD || isShufPD || 526a31593901de573813d1d8e7884a152011641a713Evan Cheng isUnpckhPD || isUnpcklPD || isPunpckhQPD || isPunpcklQPD) { 527f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng std::vector<Constant*> Idxs; 528f2937ac4eddb5ced78a1d73206de020c6d9e440fGabor Greif Value *Op0 = CI->getArgOperand(0); 529e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng ShuffleVectorInst *SI = NULL; 5304797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng if (isLoadH || isLoadL) { 5319e9a0d5fc26878e51a58a8b57900fcbf952c2691Owen Anderson Value *Op1 = UndefValue::get(Op0->getType()); 532f2937ac4eddb5ced78a1d73206de020c6d9e440fGabor Greif Value *Addr = new BitCastInst(CI->getArgOperand(1), 533ac53a0b272452013124bfc70480aea5e41b60f40Duncan Sands Type::getDoublePtrTy(C), 5344797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng "upgraded.", CI); 5354797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng Value *Load = new LoadInst(Addr, "upgraded.", false, 8, CI); 5361d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Value *Idx = ConstantInt::get(Type::getInt32Ty(C), 0); 5374797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng Op1 = InsertElementInst::Create(Op1, Load, Idx, "upgraded.", CI); 5384797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng 5394797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng if (isLoadH) { 5401d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 0)); 5411d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 2)); 5424797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng } else { 5431d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 2)); 5441d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 1)); 5454797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng } 546af7ec975870f92245f1f1484ac80a1e2db6a0afaOwen Anderson Value *Mask = ConstantVector::get(Idxs); 5474797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng SI = new ShuffleVectorInst(Op0, Op1, Mask, "upgraded.", CI); 548e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng } else if (isMovL) { 5491d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Constant *Zero = ConstantInt::get(Type::getInt32Ty(C), 0); 5504797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng Idxs.push_back(Zero); 5514797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng Idxs.push_back(Zero); 5524797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng Idxs.push_back(Zero); 5534797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng Idxs.push_back(Zero); 554af7ec975870f92245f1f1484ac80a1e2db6a0afaOwen Anderson Value *ZeroV = ConstantVector::get(Idxs); 555f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng 5564797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng Idxs.clear(); 5571d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 4)); 5581d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 5)); 5591d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 2)); 5601d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 3)); 561af7ec975870f92245f1f1484ac80a1e2db6a0afaOwen Anderson Value *Mask = ConstantVector::get(Idxs); 5624797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng SI = new ShuffleVectorInst(ZeroV, Op0, Mask, "upgraded.", CI); 563a31593901de573813d1d8e7884a152011641a713Evan Cheng } else if (isMovSD || 564a31593901de573813d1d8e7884a152011641a713Evan Cheng isUnpckhPD || isUnpcklPD || isPunpckhQPD || isPunpcklQPD) { 565f2937ac4eddb5ced78a1d73206de020c6d9e440fGabor Greif Value *Op1 = CI->getArgOperand(1); 566e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng if (isMovSD) { 5671d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 2)); 5681d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 1)); 569a31593901de573813d1d8e7884a152011641a713Evan Cheng } else if (isUnpckhPD || isPunpckhQPD) { 5701d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 1)); 5711d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 3)); 572e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng } else { 5731d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 0)); 5741d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 2)); 575e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng } 576af7ec975870f92245f1f1484ac80a1e2db6a0afaOwen Anderson Value *Mask = ConstantVector::get(Idxs); 577e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng SI = new ShuffleVectorInst(Op0, Op1, Mask, "upgraded.", CI); 578e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng } else if (isShufPD) { 579f2937ac4eddb5ced78a1d73206de020c6d9e440fGabor Greif Value *Op1 = CI->getArgOperand(1); 580a399781289092fcdceb58b21174229f4373c4191Gabor Greif unsigned MaskVal = 581a399781289092fcdceb58b21174229f4373c4191Gabor Greif cast<ConstantInt>(CI->getArgOperand(2))->getZExtValue(); 5821d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), MaskVal & 1)); 5831d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 584f81b57694b3c34a79b1464ffd21e6768c8d22662Owen Anderson ((MaskVal >> 1) & 1)+2)); 585af7ec975870f92245f1f1484ac80a1e2db6a0afaOwen Anderson Value *Mask = ConstantVector::get(Idxs); 586e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng SI = new ShuffleVectorInst(Op0, Op1, Mask, "upgraded.", CI); 5874797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng } 588f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng 589e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng assert(SI && "Unexpected!"); 590e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng 591f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng // Handle any uses of the old CallInst. 592f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng if (!CI->use_empty()) 593f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng // Replace all uses of the old call with the new cast which has the 594f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng // correct type. 595f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng CI->replaceAllUsesWith(SI); 596f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng 597f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng // Clean up the old call now that it has been completely upgraded. 598f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng CI->eraseFromParent(); 5998258d0b4bfd5fe40c29fa19e24c23ba3ac157e23Eric Christopher } else if (F->getName() == "llvm.x86.sse41.pmulld") { 6008258d0b4bfd5fe40c29fa19e24c23ba3ac157e23Eric Christopher // Upgrade this set of intrinsics into vector multiplies. 601f2937ac4eddb5ced78a1d73206de020c6d9e440fGabor Greif Instruction *Mul = BinaryOperator::CreateMul(CI->getArgOperand(0), 602f2937ac4eddb5ced78a1d73206de020c6d9e440fGabor Greif CI->getArgOperand(1), 6038258d0b4bfd5fe40c29fa19e24c23ba3ac157e23Eric Christopher CI->getName(), 6048258d0b4bfd5fe40c29fa19e24c23ba3ac157e23Eric Christopher CI); 6058258d0b4bfd5fe40c29fa19e24c23ba3ac157e23Eric Christopher // Fix up all the uses with our new multiply. 6068258d0b4bfd5fe40c29fa19e24c23ba3ac157e23Eric Christopher if (!CI->use_empty()) 6078258d0b4bfd5fe40c29fa19e24c23ba3ac157e23Eric Christopher CI->replaceAllUsesWith(Mul); 6088258d0b4bfd5fe40c29fa19e24c23ba3ac157e23Eric Christopher 6098258d0b4bfd5fe40c29fa19e24c23ba3ac157e23Eric Christopher // Remove upgraded multiply. 6108258d0b4bfd5fe40c29fa19e24c23ba3ac157e23Eric Christopher CI->eraseFromParent(); 6116d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher } else if (F->getName() == "llvm.x86.ssse3.palign.r") { 612cfbb7d43299a2ce94b83ced4a1cbcfe69e387b52Gabor Greif Value *Op1 = CI->getArgOperand(0); 613cfbb7d43299a2ce94b83ced4a1cbcfe69e387b52Gabor Greif Value *Op2 = CI->getArgOperand(1); 614cfbb7d43299a2ce94b83ced4a1cbcfe69e387b52Gabor Greif Value *Op3 = CI->getArgOperand(2); 6156d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher unsigned shiftVal = cast<ConstantInt>(Op3)->getZExtValue(); 6166d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Value *Rep; 6176d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher IRBuilder<> Builder(C); 6186d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Builder.SetInsertPoint(CI->getParent(), CI); 6196d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 6206d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // If palignr is shifting the pair of input vectors less than 9 bytes, 6216d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // emit a shuffle instruction. 6226d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher if (shiftVal <= 8) { 6236d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher const Type *IntTy = Type::getInt32Ty(C); 6246d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher const Type *EltTy = Type::getInt8Ty(C); 6256d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher const Type *VecTy = VectorType::get(EltTy, 8); 6266d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 6276d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Op2 = Builder.CreateBitCast(Op2, VecTy); 6286d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Op1 = Builder.CreateBitCast(Op1, VecTy); 6296d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 6306d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher llvm::SmallVector<llvm::Constant*, 8> Indices; 6316d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher for (unsigned i = 0; i != 8; ++i) 6326d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Indices.push_back(ConstantInt::get(IntTy, shiftVal + i)); 6336d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 6346d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Value *SV = ConstantVector::get(Indices.begin(), Indices.size()); 6356d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Rep = Builder.CreateShuffleVector(Op2, Op1, SV, "palignr"); 6366d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Rep = Builder.CreateBitCast(Rep, F->getReturnType()); 6376d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher } 6386d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 6396d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // If palignr is shifting the pair of input vectors more than 8 but less 6406d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // than 16 bytes, emit a logical right shift of the destination. 6416d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher else if (shiftVal < 16) { 6426d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // MMX has these as 1 x i64 vectors for some odd optimization reasons. 6436d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher const Type *EltTy = Type::getInt64Ty(C); 6446d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher const Type *VecTy = VectorType::get(EltTy, 1); 6456d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 6466d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Op1 = Builder.CreateBitCast(Op1, VecTy, "cast"); 6476d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Op2 = ConstantInt::get(VecTy, (shiftVal-8) * 8); 6486d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 6496d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // create i32 constant 6506d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Function *I = 6516d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Intrinsic::getDeclaration(F->getParent(), Intrinsic::x86_mmx_psrl_q); 6526d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Rep = Builder.CreateCall2(I, Op1, Op2, "palignr"); 6536d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher } 6546d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 6556d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // If palignr is shifting the pair of vectors more than 32 bytes, emit zero. 6566d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher else { 6576d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Rep = Constant::getNullValue(F->getReturnType()); 6586d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher } 6596d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 6606d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // Replace any uses with our new instruction. 6616d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher if (!CI->use_empty()) 6626d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher CI->replaceAllUsesWith(Rep); 6636d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 6646d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // Remove upgraded instruction. 6656d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher CI->eraseFromParent(); 6666d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 6676d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher } else if (F->getName() == "llvm.x86.ssse3.palign.r.128") { 668cfbb7d43299a2ce94b83ced4a1cbcfe69e387b52Gabor Greif Value *Op1 = CI->getArgOperand(0); 669cfbb7d43299a2ce94b83ced4a1cbcfe69e387b52Gabor Greif Value *Op2 = CI->getArgOperand(1); 670cfbb7d43299a2ce94b83ced4a1cbcfe69e387b52Gabor Greif Value *Op3 = CI->getArgOperand(2); 6716d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher unsigned shiftVal = cast<ConstantInt>(Op3)->getZExtValue(); 6726d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Value *Rep; 6736d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher IRBuilder<> Builder(C); 6746d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Builder.SetInsertPoint(CI->getParent(), CI); 6756d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 6766d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // If palignr is shifting the pair of input vectors less than 17 bytes, 6776d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // emit a shuffle instruction. 6786d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher if (shiftVal <= 16) { 6796d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher const Type *IntTy = Type::getInt32Ty(C); 6806d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher const Type *EltTy = Type::getInt8Ty(C); 6816d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher const Type *VecTy = VectorType::get(EltTy, 16); 6826d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 6836d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Op2 = Builder.CreateBitCast(Op2, VecTy); 6846d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Op1 = Builder.CreateBitCast(Op1, VecTy); 6856d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 6866d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher llvm::SmallVector<llvm::Constant*, 16> Indices; 6876d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher for (unsigned i = 0; i != 16; ++i) 6886d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Indices.push_back(ConstantInt::get(IntTy, shiftVal + i)); 6896d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 6906d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Value *SV = ConstantVector::get(Indices.begin(), Indices.size()); 6916d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Rep = Builder.CreateShuffleVector(Op2, Op1, SV, "palignr"); 6926d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Rep = Builder.CreateBitCast(Rep, F->getReturnType()); 6936d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher } 6946d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 6956d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // If palignr is shifting the pair of input vectors more than 16 but less 6966d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // than 32 bytes, emit a logical right shift of the destination. 6976d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher else if (shiftVal < 32) { 6986d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher const Type *EltTy = Type::getInt64Ty(C); 6996d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher const Type *VecTy = VectorType::get(EltTy, 2); 7006d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher const Type *IntTy = Type::getInt32Ty(C); 7016d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 7026d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Op1 = Builder.CreateBitCast(Op1, VecTy, "cast"); 7036d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Op2 = ConstantInt::get(IntTy, (shiftVal-16) * 8); 7046d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 7056d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // create i32 constant 7066d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Function *I = 7076d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Intrinsic::getDeclaration(F->getParent(), Intrinsic::x86_sse2_psrl_dq); 7086d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Rep = Builder.CreateCall2(I, Op1, Op2, "palignr"); 7096d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher } 7106d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 7116d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // If palignr is shifting the pair of vectors more than 32 bytes, emit zero. 7126d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher else { 7136d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Rep = Constant::getNullValue(F->getReturnType()); 7146d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher } 7156d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 7166d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // Replace any uses with our new instruction. 7176d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher if (!CI->use_empty()) 7186d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher CI->replaceAllUsesWith(Rep); 7196d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 7206d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // Remove upgraded instruction. 7216d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher CI->eraseFromParent(); 7226d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 723a5cecd0a130f7ebc4787f8f5b3e8959e41786673Evan Cheng } else { 724c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable("Unknown function for CallInst upgrade."); 725f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng } 726f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng return; 727f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng } 728f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng 729051a950000e21935165db56695e35bade668193bGabor Greif switch (NewFn->getIntrinsicID()) { 730eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson default: llvm_unreachable("Unknown function for CallInst upgrade."); 7317a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson case Intrinsic::arm_neon_vld1: 7327a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson case Intrinsic::arm_neon_vld2: 7337a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson case Intrinsic::arm_neon_vld3: 7347a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson case Intrinsic::arm_neon_vld4: 7357a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson case Intrinsic::arm_neon_vst1: 7367a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson case Intrinsic::arm_neon_vst2: 7377a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson case Intrinsic::arm_neon_vst3: 7387a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson case Intrinsic::arm_neon_vst4: 7397a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson case Intrinsic::arm_neon_vld2lane: 7407a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson case Intrinsic::arm_neon_vld3lane: 7417a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson case Intrinsic::arm_neon_vld4lane: 7427a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson case Intrinsic::arm_neon_vst2lane: 7437a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson case Intrinsic::arm_neon_vst3lane: 7447a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson case Intrinsic::arm_neon_vst4lane: { 7457a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson // Add a default alignment argument of 1. 7467a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson SmallVector<Value*, 8> Operands(CS.arg_begin(), CS.arg_end()); 7477a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson Operands.push_back(ConstantInt::get(Type::getInt32Ty(C), 1)); 7487a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson CallInst *NewCI = CallInst::Create(NewFn, Operands.begin(), Operands.end(), 7497a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson CI->getName(), CI); 7507a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson NewCI->setTailCall(CI->isTailCall()); 7517a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson NewCI->setCallingConv(CI->getCallingConv()); 7527a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson 7537a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson // Handle any uses of the old CallInst. 7547a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson if (!CI->use_empty()) 7557a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson // Replace all uses of the old call with the new cast which has the 7567a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson // correct type. 7577a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson CI->replaceAllUsesWith(NewCI); 7587a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson 7597a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson // Clean up the old call now that it has been completely upgraded. 7607a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson CI->eraseFromParent(); 7617a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson break; 7627a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson } 7637a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson 764d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson case Intrinsic::x86_mmx_psll_d: 765d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson case Intrinsic::x86_mmx_psll_q: 766d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson case Intrinsic::x86_mmx_psll_w: 767d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson case Intrinsic::x86_mmx_psra_d: 768d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson case Intrinsic::x86_mmx_psra_w: 769d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson case Intrinsic::x86_mmx_psrl_d: 770d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson case Intrinsic::x86_mmx_psrl_q: 771d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson case Intrinsic::x86_mmx_psrl_w: { 77258d74910c6b82e622ecbb57d6644d48fec5a5c0fChris Lattner Value *Operands[2]; 773d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson 774f2937ac4eddb5ced78a1d73206de020c6d9e440fGabor Greif Operands[0] = CI->getArgOperand(0); 775d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson 776d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson // Cast the second parameter to the correct type. 777f2937ac4eddb5ced78a1d73206de020c6d9e440fGabor Greif BitCastInst *BC = new BitCastInst(CI->getArgOperand(1), 778d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson NewFn->getFunctionType()->getParamType(1), 7794797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng "upgraded.", CI); 78058d74910c6b82e622ecbb57d6644d48fec5a5c0fChris Lattner Operands[1] = BC; 781d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson 782d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson // Construct a new CallInst 783051a950000e21935165db56695e35bade668193bGabor Greif CallInst *NewCI = CallInst::Create(NewFn, Operands, Operands+2, 784051a950000e21935165db56695e35bade668193bGabor Greif "upgraded."+CI->getName(), CI); 785d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson NewCI->setTailCall(CI->isTailCall()); 786d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson NewCI->setCallingConv(CI->getCallingConv()); 787d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson 788d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson // Handle any uses of the old CallInst. 789d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson if (!CI->use_empty()) 790d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson // Replace all uses of the old call with the new cast which has the 791d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson // correct type. 792d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson CI->replaceAllUsesWith(NewCI); 793d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson 794d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson // Clean up the old call now that it has been completely upgraded. 795d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson CI->eraseFromParent(); 796d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson break; 797d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson } 7986994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth case Intrinsic::ctlz: 7996994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth case Intrinsic::ctpop: 800051a950000e21935165db56695e35bade668193bGabor Greif case Intrinsic::cttz: { 801bb6eabf4f5b518a333ab4cedce910962ff935e3aGabor Greif // Build a small vector of the original arguments. 802bb6eabf4f5b518a333ab4cedce910962ff935e3aGabor Greif SmallVector<Value*, 8> Operands(CS.arg_begin(), CS.arg_end()); 8036994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 8046994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // Construct a new CallInst 805051a950000e21935165db56695e35bade668193bGabor Greif CallInst *NewCI = CallInst::Create(NewFn, Operands.begin(), Operands.end(), 806051a950000e21935165db56695e35bade668193bGabor Greif "upgraded."+CI->getName(), CI); 8076994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth NewCI->setTailCall(CI->isTailCall()); 8086994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth NewCI->setCallingConv(CI->getCallingConv()); 8096994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 8106994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // Handle any uses of the old CallInst. 8116994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth if (!CI->use_empty()) { 8126994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // Check for sign extend parameter attributes on the return values. 8130598866c052147c31b808391f58434ce3dbfb838Devang Patel bool SrcSExt = NewFn->getAttributes().paramHasAttr(0, Attribute::SExt); 8140598866c052147c31b808391f58434ce3dbfb838Devang Patel bool DestSExt = F->getAttributes().paramHasAttr(0, Attribute::SExt); 8156994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 8166994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // Construct an appropriate cast from the new return type to the old. 8177cbd8a3e92221437048b484d5ef9c0a22d0f8c58Gabor Greif CastInst *RetCast = CastInst::Create( 8186994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth CastInst::getCastOpcode(NewCI, SrcSExt, 8196994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth F->getReturnType(), 8206994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth DestSExt), 8216994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth NewCI, F->getReturnType(), 8226994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth NewCI->getName(), CI); 8236994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth NewCI->moveBefore(RetCast); 8246994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 8256994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // Replace all uses of the old call with the new cast which has the 8266994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // correct type. 8276994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth CI->replaceAllUsesWith(RetCast); 8286994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth } 8296994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 8306994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // Clean up the old call now that it has been completely upgraded. 8316994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth CI->eraseFromParent(); 832051a950000e21935165db56695e35bade668193bGabor Greif } 833051a950000e21935165db56695e35bade668193bGabor Greif break; 834b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands case Intrinsic::eh_selector: 835b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands case Intrinsic::eh_typeid_for: { 836b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands // Only the return type changed. 837bb6eabf4f5b518a333ab4cedce910962ff935e3aGabor Greif SmallVector<Value*, 8> Operands(CS.arg_begin(), CS.arg_end()); 838b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands CallInst *NewCI = CallInst::Create(NewFn, Operands.begin(), Operands.end(), 839b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands "upgraded." + CI->getName(), CI); 840b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands NewCI->setTailCall(CI->isTailCall()); 841b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands NewCI->setCallingConv(CI->getCallingConv()); 842b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands 843b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands // Handle any uses of the old CallInst. 844b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands if (!CI->use_empty()) { 845b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands // Construct an appropriate cast from the new return type to the old. 846b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands CastInst *RetCast = 847b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands CastInst::Create(CastInst::getCastOpcode(NewCI, true, 848b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands F->getReturnType(), true), 849b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands NewCI, F->getReturnType(), NewCI->getName(), CI); 850b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands CI->replaceAllUsesWith(RetCast); 851b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands } 852b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands CI->eraseFromParent(); 853b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands } 854b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands break; 85520adc9dc4650313f017b27d9818eb2176238113dMon P Wang case Intrinsic::memcpy: 85620adc9dc4650313f017b27d9818eb2176238113dMon P Wang case Intrinsic::memmove: 85720adc9dc4650313f017b27d9818eb2176238113dMon P Wang case Intrinsic::memset: { 85820adc9dc4650313f017b27d9818eb2176238113dMon P Wang // Add isVolatile 85920adc9dc4650313f017b27d9818eb2176238113dMon P Wang const llvm::Type *I1Ty = llvm::Type::getInt1Ty(CI->getContext()); 860f2937ac4eddb5ced78a1d73206de020c6d9e440fGabor Greif Value *Operands[5] = { CI->getArgOperand(0), CI->getArgOperand(1), 861f2937ac4eddb5ced78a1d73206de020c6d9e440fGabor Greif CI->getArgOperand(2), CI->getArgOperand(3), 86220adc9dc4650313f017b27d9818eb2176238113dMon P Wang llvm::ConstantInt::get(I1Ty, 0) }; 86320adc9dc4650313f017b27d9818eb2176238113dMon P Wang CallInst *NewCI = CallInst::Create(NewFn, Operands, Operands+5, 86420adc9dc4650313f017b27d9818eb2176238113dMon P Wang CI->getName(), CI); 86520adc9dc4650313f017b27d9818eb2176238113dMon P Wang NewCI->setTailCall(CI->isTailCall()); 86620adc9dc4650313f017b27d9818eb2176238113dMon P Wang NewCI->setCallingConv(CI->getCallingConv()); 86720adc9dc4650313f017b27d9818eb2176238113dMon P Wang // Handle any uses of the old CallInst. 86820adc9dc4650313f017b27d9818eb2176238113dMon P Wang if (!CI->use_empty()) 86920adc9dc4650313f017b27d9818eb2176238113dMon P Wang // Replace all uses of the old call with the new cast which has the 87020adc9dc4650313f017b27d9818eb2176238113dMon P Wang // correct type. 87120adc9dc4650313f017b27d9818eb2176238113dMon P Wang CI->replaceAllUsesWith(NewCI); 87220adc9dc4650313f017b27d9818eb2176238113dMon P Wang 87320adc9dc4650313f017b27d9818eb2176238113dMon P Wang // Clean up the old call now that it has been completely upgraded. 87420adc9dc4650313f017b27d9818eb2176238113dMon P Wang CI->eraseFromParent(); 87520adc9dc4650313f017b27d9818eb2176238113dMon P Wang break; 87620adc9dc4650313f017b27d9818eb2176238113dMon P Wang } 8776994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth } 8786994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth} 8796994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 8806994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth// This tests each Function to determine if it needs upgrading. When we find 8816994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth// one we are interested in, we then upgrade all calls to reflect the new 8826994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth// function. 8836994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruthvoid llvm::UpgradeCallsToIntrinsic(Function* F) { 8846994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth assert(F && "Illegal attempt to upgrade a non-existent intrinsic."); 8856994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 8866994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // Upgrade the function and check if it is a totaly new function. 887f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng Function* NewFn; 888f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng if (UpgradeIntrinsicFunction(F, NewFn)) { 8896994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth if (NewFn != F) { 8906994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // Replace all uses to the old function with the new one if necessary. 8916994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth for (Value::use_iterator UI = F->use_begin(), UE = F->use_end(); 8926994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth UI != UE; ) { 8936994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth if (CallInst* CI = dyn_cast<CallInst>(*UI++)) 8946994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth UpgradeIntrinsicCall(CI, NewFn); 8956994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth } 8966994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // Remove old function, no longer used, from the module. 8976994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth F->eraseFromParent(); 8986994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth } 8996994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth } 9006994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth} 901e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel 902771150accba7ab3480746a451710ac81f950fac2Victor Hernandez/// This function strips all debug info intrinsics, except for llvm.dbg.declare. 903771150accba7ab3480746a451710ac81f950fac2Victor Hernandez/// If an llvm.dbg.declare intrinsic is invalid, then this function simply 904771150accba7ab3480746a451710ac81f950fac2Victor Hernandez/// strips that use. 905e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patelvoid llvm::CheckDebugInfoIntrinsics(Module *M) { 906e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel 907e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel 908e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel if (Function *FuncStart = M->getFunction("llvm.dbg.func.start")) { 90944a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel while (!FuncStart->use_empty()) { 91044a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel CallInst *CI = cast<CallInst>(FuncStart->use_back()); 91144a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel CI->eraseFromParent(); 912e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel } 91344a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel FuncStart->eraseFromParent(); 914e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel } 91544a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel 916e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel if (Function *StopPoint = M->getFunction("llvm.dbg.stoppoint")) { 91744a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel while (!StopPoint->use_empty()) { 91844a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel CallInst *CI = cast<CallInst>(StopPoint->use_back()); 91944a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel CI->eraseFromParent(); 920e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel } 92144a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel StopPoint->eraseFromParent(); 922e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel } 923e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel 924e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel if (Function *RegionStart = M->getFunction("llvm.dbg.region.start")) { 92544a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel while (!RegionStart->use_empty()) { 92644a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel CallInst *CI = cast<CallInst>(RegionStart->use_back()); 92744a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel CI->eraseFromParent(); 928e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel } 92944a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel RegionStart->eraseFromParent(); 930e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel } 931e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel 932e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel if (Function *RegionEnd = M->getFunction("llvm.dbg.region.end")) { 93344a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel while (!RegionEnd->use_empty()) { 93444a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel CallInst *CI = cast<CallInst>(RegionEnd->use_back()); 93544a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel CI->eraseFromParent(); 936e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel } 93744a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel RegionEnd->eraseFromParent(); 938e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel } 939e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel 940e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel if (Function *Declare = M->getFunction("llvm.dbg.declare")) { 941e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel if (!Declare->use_empty()) { 942e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel DbgDeclareInst *DDI = cast<DbgDeclareInst>(Declare->use_back()); 943f2937ac4eddb5ced78a1d73206de020c6d9e440fGabor Greif if (!isa<MDNode>(DDI->getArgOperand(0)) || 944f2937ac4eddb5ced78a1d73206de020c6d9e440fGabor Greif !isa<MDNode>(DDI->getArgOperand(1))) { 945e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel while (!Declare->use_empty()) { 946e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel CallInst *CI = cast<CallInst>(Declare->use_back()); 947e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel CI->eraseFromParent(); 948e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel } 949e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel Declare->eraseFromParent(); 950e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel } 951e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel } 952e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel } 953e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel} 954