AutoUpgrade.cpp revision 0488fb649a56b7fc89a5814df5308813f9e5a85d
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 2910488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen // x86_mmx instead of a v1i64, v2i32, v4i16, or v8i8. 2920488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen if (Name.compare(5, 8, "x86.mmx.", 8) == 0) { 2930488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen const Type *X86_MMXTy = VectorType::getX86_MMXTy(FTy->getContext()); 2940488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 2950488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen if (Name.compare(13, 4, "padd", 4) == 0 || 2960488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Name.compare(13, 4, "psub", 4) == 0 || 2970488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Name.compare(13, 4, "pmul", 4) == 0 || 2980488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Name.compare(13, 5, "pmadd", 5) == 0 || 2990488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Name.compare(13, 4, "pand", 4) == 0 || 3000488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Name.compare(13, 3, "por", 3) == 0 || 3010488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Name.compare(13, 4, "pxor", 4) == 0 || 3020488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Name.compare(13, 4, "pavg", 4) == 0 || 3030488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Name.compare(13, 4, "pmax", 4) == 0 || 3040488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Name.compare(13, 4, "pmin", 4) == 0 || 3050488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Name.compare(13, 4, "psad", 4) == 0 || 3060488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Name.compare(13, 4, "psll", 4) == 0 || 3070488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Name.compare(13, 4, "psrl", 4) == 0 || 3080488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Name.compare(13, 4, "psra", 4) == 0 || 3090488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Name.compare(13, 4, "pack", 4) == 0 || 3100488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Name.compare(13, 6, "punpck", 6) == 0 || 3110488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Name.compare(13, 4, "pcmp", 4) == 0) { 3120488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen assert(FTy->getNumParams() == 2 && "MMX intrinsic takes 2 args!"); 3130488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen const Type *SecondParamTy = X86_MMXTy; 3140488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 3150488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen if (Name.compare(13, 5, "pslli", 5) == 0 || 3160488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Name.compare(13, 5, "psrli", 5) == 0 || 3170488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Name.compare(13, 5, "psrai", 5) == 0) 3180488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen SecondParamTy = FTy->getParamType(1); 3190488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 3200488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen // Don't do anything if it has the correct types. 3210488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen if (FTy->getReturnType() == X86_MMXTy && 3220488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen FTy->getParamType(0) == X86_MMXTy && 3230488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen FTy->getParamType(1) == SecondParamTy) 3240488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen break; 3250488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 3260488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen // We first need to change the name of the old (bad) intrinsic, because 3270488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen // its type is incorrect, but we cannot overload that name. We 3280488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen // arbitrarily unique it here allowing us to construct a correctly named 3290488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen // and typed function below. 3300488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen F->setName(""); 3310488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 3320488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen // Now construct the new intrinsic with the correct name and type. We 3330488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen // leave the old function around in order to query its type, whatever it 3340488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen // may be, and correctly convert up to the new type. 3350488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen NewFn = cast<Function>(M->getOrInsertFunction(Name, 3360488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen X86_MMXTy, X86_MMXTy, 3370488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen SecondParamTy, (Type*)0)); 3380488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen return true; 3390488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen } 3400488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 3410488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen if (Name.compare(13, 8, "maskmovq", 8) == 0) { 3420488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen // Don't do anything if it has the correct types. 3430488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen if (FTy->getParamType(0) == X86_MMXTy && 3440488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen FTy->getParamType(1) == X86_MMXTy) 3450488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen break; 3460488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 3470488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen F->setName(""); 3480488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen NewFn = cast<Function>(M->getOrInsertFunction(Name, 3490488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen FTy->getReturnType(), 3500488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen X86_MMXTy, 3510488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen X86_MMXTy, 3520488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen FTy->getParamType(2), 3530488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen (Type*)0)); 3540488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen return true; 3550488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen } 3560488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 3570488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen if (Name.compare(13, 8, "pmovmskb", 8) == 0) { 3580488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen if (FTy->getParamType(0) == X86_MMXTy) 3590488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen break; 3600488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 3610488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen F->setName(""); 3620488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen NewFn = cast<Function>(M->getOrInsertFunction(Name, 3630488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen FTy->getReturnType(), 3640488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen X86_MMXTy, 3650488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen (Type*)0)); 3660488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen return true; 3670488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen } 3680488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 3690488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen if (Name.compare(13, 5, "movnt", 5) == 0) { 3700488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen if (FTy->getParamType(1) == X86_MMXTy) 3710488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen break; 3720488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 3730488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen F->setName(""); 3740488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen NewFn = cast<Function>(M->getOrInsertFunction(Name, 3750488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen FTy->getReturnType(), 3760488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen FTy->getParamType(0), 3770488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen X86_MMXTy, 3780488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen (Type*)0)); 3790488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen return true; 3800488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen } 3810488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 3820488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen if (Name.compare(13, 7, "palignr", 7) == 0) { 3830488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen if (FTy->getReturnType() == X86_MMXTy && 3840488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen FTy->getParamType(0) == X86_MMXTy && 3850488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen FTy->getParamType(1) == X86_MMXTy) 3860488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen break; 3870488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 3880488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen F->setName(""); 3890488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen NewFn = cast<Function>(M->getOrInsertFunction(Name, 3900488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen X86_MMXTy, 3910488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen X86_MMXTy, 3920488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen X86_MMXTy, 3930488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen FTy->getParamType(2), 3940488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen (Type*)0)); 3950488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen return true; 3960488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen } 3970488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 3980488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen if (Name.compare(13, 5, "pextr", 5) == 0) { 3990488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen if (FTy->getParamType(0) == X86_MMXTy) 4000488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen break; 4010488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 4020488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen F->setName(""); 4030488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen NewFn = cast<Function>(M->getOrInsertFunction(Name, 4040488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen FTy->getReturnType(), 4050488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen X86_MMXTy, 4060488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen FTy->getParamType(1), 4070488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen (Type*)0)); 4080488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen return true; 4090488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen } 4100488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 4110488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen if (Name.compare(13, 5, "pinsr", 5) == 0) { 4120488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen if (FTy->getReturnType() == X86_MMXTy && 4130488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen FTy->getParamType(0) == X86_MMXTy) 4140488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen break; 4150488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 4160488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen F->setName(""); 4170488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen NewFn = cast<Function>(M->getOrInsertFunction(Name, 4180488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen X86_MMXTy, 4190488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen X86_MMXTy, 4200488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen FTy->getParamType(1), 4210488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen FTy->getParamType(2), 4220488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen (Type*)0)); 4230488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen return true; 4240488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen } 4250488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 4260488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen if (Name.compare(13, 12, "cvtsi32.si64", 12) == 0) { 4270488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen if (FTy->getReturnType() == X86_MMXTy) 4280488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen break; 4290488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 4300488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen F->setName(""); 4310488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen NewFn = cast<Function>(M->getOrInsertFunction(Name, 4320488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen X86_MMXTy, 4330488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen FTy->getParamType(0), 4340488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen (Type*)0)); 4350488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen return true; 4360488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen } 4370488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 4380488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen if (Name.compare(13, 12, "cvtsi64.si32", 12) == 0) { 4390488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen if (FTy->getParamType(0) == X86_MMXTy) 4400488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen break; 4410488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 4420488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen F->setName(""); 4430488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen NewFn = cast<Function>(M->getOrInsertFunction(Name, 4440488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen FTy->getReturnType(), 4450488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen X86_MMXTy, 4460488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen (Type*)0)); 4470488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen return true; 4480488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen } 4490488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 4500488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen if (Name.compare(13, 8, "vec.init", 8) == 0) { 4510488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen if (FTy->getReturnType() == X86_MMXTy) 4520488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen break; 4530488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 4540488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen F->setName(""); 4550488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 4560488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen if (Name.compare(21, 2, ".b", 2) == 0) 4570488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen NewFn = cast<Function>(M->getOrInsertFunction(Name, 4580488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen X86_MMXTy, 4590488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen FTy->getParamType(0), 4600488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen FTy->getParamType(1), 4610488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen FTy->getParamType(2), 4620488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen FTy->getParamType(3), 4630488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen FTy->getParamType(4), 4640488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen FTy->getParamType(5), 4650488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen FTy->getParamType(6), 4660488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen FTy->getParamType(7), 4670488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen (Type*)0)); 4680488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen else if (Name.compare(21, 2, ".w", 2) == 0) 4690488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen NewFn = cast<Function>(M->getOrInsertFunction(Name, 4700488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen X86_MMXTy, 4710488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen FTy->getParamType(0), 4720488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen FTy->getParamType(1), 4730488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen FTy->getParamType(2), 4740488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen FTy->getParamType(3), 4750488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen (Type*)0)); 4760488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen else if (Name.compare(21, 2, ".d", 2) == 0) 4770488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen NewFn = cast<Function>(M->getOrInsertFunction(Name, 4780488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen X86_MMXTy, 4790488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen FTy->getParamType(0), 4800488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen FTy->getParamType(1), 4810488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen (Type*)0)); 4820488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen return true; 4830488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen } 4840488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 4850488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 4860488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen if (Name.compare(13, 9, "vec.ext.d", 9) == 0) { 4870488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen if (FTy->getReturnType() == X86_MMXTy && 4880488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen FTy->getParamType(0) == X86_MMXTy) 4890488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen break; 4900488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 4910488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen F->setName(""); 4920488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen NewFn = cast<Function>(M->getOrInsertFunction(Name, 4930488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen X86_MMXTy, 4940488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen X86_MMXTy, 4950488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen FTy->getParamType(1), 4960488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen (Type*)0)); 4970488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen return true; 4980488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen } 4990488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 5000488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen if (Name.compare(13, 9, "emms", 4) == 0 || 5010488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Name.compare(13, 9, "femms", 5) == 0) { 5020488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen NewFn = 0; 503d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson break; 5040488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen } 505d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson 5060488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen // We really shouldn't get here ever. 5070488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen assert(0 && "Invalid MMX intrinsic!"); 5080488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen break; 5094797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng } else if (Name.compare(5,17,"x86.sse2.loadh.pd",17) == 0 || 5104797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng Name.compare(5,17,"x86.sse2.loadl.pd",17) == 0 || 511e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng Name.compare(5,16,"x86.sse2.movl.dq",16) == 0 || 512e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng Name.compare(5,15,"x86.sse2.movs.d",15) == 0 || 513e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng Name.compare(5,16,"x86.sse2.shuf.pd",16) == 0 || 514e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng Name.compare(5,18,"x86.sse2.unpckh.pd",18) == 0 || 515a31593901de573813d1d8e7884a152011641a713Evan Cheng Name.compare(5,18,"x86.sse2.unpckl.pd",18) == 0 || 516a31593901de573813d1d8e7884a152011641a713Evan Cheng Name.compare(5,20,"x86.sse2.punpckh.qdq",20) == 0 || 517a31593901de573813d1d8e7884a152011641a713Evan Cheng Name.compare(5,20,"x86.sse2.punpckl.qdq",20) == 0) { 5184797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng // Calls to these intrinsics are transformed into ShuffleVector's. 519f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng NewFn = 0; 520f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng return true; 5218258d0b4bfd5fe40c29fa19e24c23ba3ac157e23Eric Christopher } else if (Name.compare(5, 16, "x86.sse41.pmulld", 16) == 0) { 5228258d0b4bfd5fe40c29fa19e24c23ba3ac157e23Eric Christopher // Calls to these intrinsics are transformed into vector multiplies. 5238258d0b4bfd5fe40c29fa19e24c23ba3ac157e23Eric Christopher NewFn = 0; 5248258d0b4bfd5fe40c29fa19e24c23ba3ac157e23Eric Christopher return true; 5256d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher } else if (Name.compare(5, 18, "x86.ssse3.palign.r", 18) == 0 || 5266d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Name.compare(5, 22, "x86.ssse3.palign.r.128", 22) == 0) { 5276d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // Calls to these intrinsics are transformed into vector shuffles, shifts, 5286d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // or 0. 5296d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher NewFn = 0; 5306d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher return true; 531d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson } 532f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng 533d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson break; 5346994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth } 5356994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 5366994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // This may not belong here. This function is effectively being overloaded 5376994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // to both detect an intrinsic which needs upgrading, and to provide the 5386994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // upgraded form of the intrinsic. We should perhaps have two separate 5396994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // functions for this. 540f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng return false; 5416994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth} 5426994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 543f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Chengbool llvm::UpgradeIntrinsicFunction(Function *F, Function *&NewFn) { 544f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng NewFn = 0; 545f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng bool Upgraded = UpgradeIntrinsicFunction1(F, NewFn); 546a3355ffb3d30d19d226bbb75707991c60f236e37Duncan Sands 547a3355ffb3d30d19d226bbb75707991c60f236e37Duncan Sands // Upgrade intrinsic attributes. This does not change the function. 548f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng if (NewFn) 549f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng F = NewFn; 55049de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen if (unsigned id = F->getIntrinsicID()) 5510598866c052147c31b808391f58434ce3dbfb838Devang Patel F->setAttributes(Intrinsic::getAttributes((Intrinsic::ID)id)); 552a3355ffb3d30d19d226bbb75707991c60f236e37Duncan Sands return Upgraded; 553a3355ffb3d30d19d226bbb75707991c60f236e37Duncan Sands} 554a3355ffb3d30d19d226bbb75707991c60f236e37Duncan Sands 555de49f360ec4780acb382a3ae923d1716fdb0dc03Bill Wendlingbool llvm::UpgradeGlobalVariable(GlobalVariable *GV) { 556f9e49e86ee9f06c2808c6e57723c5650615e689dBill Wendling StringRef Name(GV->getName()); 557ebd3e5f4cc8656191ee56c028930c0092815518fBill Wendling 558ebd3e5f4cc8656191ee56c028930c0092815518fBill Wendling // We are only upgrading one symbol here. 559de49f360ec4780acb382a3ae923d1716fdb0dc03Bill Wendling if (Name == ".llvm.eh.catch.all.value") { 560de49f360ec4780acb382a3ae923d1716fdb0dc03Bill Wendling GV->setName("llvm.eh.catch.all.value"); 561de49f360ec4780acb382a3ae923d1716fdb0dc03Bill Wendling return true; 562de49f360ec4780acb382a3ae923d1716fdb0dc03Bill Wendling } 563de49f360ec4780acb382a3ae923d1716fdb0dc03Bill Wendling 564de49f360ec4780acb382a3ae923d1716fdb0dc03Bill Wendling return false; 565de49f360ec4780acb382a3ae923d1716fdb0dc03Bill Wendling} 566de49f360ec4780acb382a3ae923d1716fdb0dc03Bill Wendling 567d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson/// ExtendNEONArgs - For NEON "long" and "wide" operations, where the results 568d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson/// have vector elements twice as big as one or both source operands, do the 569d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson/// sign- or zero-extension that used to be handled by intrinsics. The 570d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson/// extended values are returned via V0 and V1. 571d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilsonstatic void ExtendNEONArgs(CallInst *CI, Value *Arg0, Value *Arg1, 572d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson Value *&V0, Value *&V1) { 573d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson Function *F = CI->getCalledFunction(); 574d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson const std::string& Name = F->getName(); 575d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson bool isLong = (Name.at(18) == 'l'); 576d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson bool isSigned = (Name.at(19) == 's'); 577d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson 578d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson if (isSigned) { 579d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson if (isLong) 580d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson V0 = new SExtInst(Arg0, CI->getType(), "", CI); 581d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson else 582d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson V0 = Arg0; 583d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson V1 = new SExtInst(Arg1, CI->getType(), "", CI); 584d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson } else { 585d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson if (isLong) 586d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson V0 = new ZExtInst(Arg0, CI->getType(), "", CI); 587d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson else 588d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson V0 = Arg0; 589d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson V1 = new ZExtInst(Arg1, CI->getType(), "", CI); 590d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson } 591d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson} 592d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson 593eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson/// CallVABD - As part of expanding a call to one of the old NEON vabdl, vaba, 594eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson/// or vabal intrinsics, construct a call to a vabd intrinsic. Examine the 595eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson/// name of the old intrinsic to determine whether to use a signed or unsigned 596eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson/// vabd intrinsic. Get the type from the old call instruction, adjusted for 597eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson/// half-size vector elements if the old intrinsic was vabdl or vabal. 598eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilsonstatic Instruction *CallVABD(CallInst *CI, Value *Arg0, Value *Arg1) { 599eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson Function *F = CI->getCalledFunction(); 600eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson const std::string& Name = F->getName(); 601eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson bool isLong = (Name.at(18) == 'l'); 602eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson bool isSigned = (Name.at(isLong ? 19 : 18) == 's'); 603eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson 604eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson Intrinsic::ID intID; 605eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson if (isSigned) 606eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson intID = Intrinsic::arm_neon_vabds; 607eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson else 608eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson intID = Intrinsic::arm_neon_vabdu; 609eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson 610eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson const Type *Ty = CI->getType(); 611eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson if (isLong) 612eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson Ty = VectorType::getTruncatedElementVectorType(cast<const VectorType>(Ty)); 613eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson 614eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson Function *VABD = Intrinsic::getDeclaration(F->getParent(), intID, &Ty, 1); 615eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson Value *Operands[2]; 616eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson Operands[0] = Arg0; 617eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson Operands[1] = Arg1; 618eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson return CallInst::Create(VABD, Operands, Operands+2, 619eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson "upgraded."+CI->getName(), CI); 620eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson} 621eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson 6220488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen/// ConstructNewCallInst - Construct a new CallInst with the signature of NewFn. 6230488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesenstatic void ConstructNewCallInst(Function *NewFn, CallInst *OldCI, 6240488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Value **Operands, unsigned NumOps, 6250488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen bool AssignName = true) { 6260488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen // Construct a new CallInst. 6270488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen CallInst *NewCI = 6280488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen CallInst::Create(NewFn, Operands, Operands + NumOps, 6290488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen AssignName ? "upgraded." + OldCI->getName() : "", OldCI); 6300488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 6310488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen NewCI->setTailCall(OldCI->isTailCall()); 6320488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen NewCI->setCallingConv(OldCI->getCallingConv()); 6330488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 6340488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen // Handle any uses of the old CallInst. 6350488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen if (!OldCI->use_empty()) { 6360488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen // If the type has changed, add a cast. 6370488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Instruction *I = OldCI; 6380488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen if (OldCI->getType() != NewCI->getType()) { 6390488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Function *OldFn = OldCI->getCalledFunction(); 6400488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen CastInst *RetCast = 6410488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen CastInst::Create(CastInst::getCastOpcode(NewCI, true, 6420488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen OldFn->getReturnType(), true), 6430488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen NewCI, OldFn->getReturnType(), NewCI->getName(),OldCI); 6440488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen I = RetCast; 6450488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen } 6460488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen // Replace all uses of the old call with the new cast which has the 6470488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen // correct type. 6480488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen OldCI->replaceAllUsesWith(I); 6490488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen } 6500488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen // Clean up the old call now that it has been completely upgraded. 6510488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen OldCI->eraseFromParent(); 6520488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen} 6530488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 6546994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth// UpgradeIntrinsicCall - Upgrade a call to an old intrinsic to be a call the 6556994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth// upgraded intrinsic. All argument and return casting must be provided in 6566994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth// order to seamlessly integrate with existing context. 6576994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruthvoid llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { 6586994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth Function *F = CI->getCalledFunction(); 6591d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson LLVMContext &C = CI->getContext(); 660bb6eabf4f5b518a333ab4cedce910962ff935e3aGabor Greif ImmutableCallSite CS(CI); 661bb6eabf4f5b518a333ab4cedce910962ff935e3aGabor Greif 6626994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth assert(F && "CallInst has no function associated with it."); 663f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng 664f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng if (!NewFn) { 665b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson // Get the Function's name. 666b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson const std::string& Name = F->getName(); 667b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson 668b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson // Upgrade ARM NEON intrinsics. 669b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson if (Name.compare(5, 9, "arm.neon.", 9) == 0) { 670b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson Instruction *NewI; 671d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson Value *V0, *V1; 672b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson if (Name.compare(14, 7, "vmovls.", 7) == 0) { 673b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson NewI = new SExtInst(CI->getArgOperand(0), CI->getType(), 674b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson "upgraded." + CI->getName(), CI); 675b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson } else if (Name.compare(14, 7, "vmovlu.", 7) == 0) { 676b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson NewI = new ZExtInst(CI->getArgOperand(0), CI->getType(), 677b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson "upgraded." + CI->getName(), CI); 678d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson } else if (Name.compare(14, 4, "vadd", 4) == 0) { 679d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson ExtendNEONArgs(CI, CI->getArgOperand(0), CI->getArgOperand(1), V0, V1); 680d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson NewI = BinaryOperator::CreateAdd(V0, V1, "upgraded."+CI->getName(), CI); 681d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson } else if (Name.compare(14, 4, "vsub", 4) == 0) { 682d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson ExtendNEONArgs(CI, CI->getArgOperand(0), CI->getArgOperand(1), V0, V1); 683d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson NewI = BinaryOperator::CreateSub(V0, V1,"upgraded."+CI->getName(),CI); 684d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson } else if (Name.compare(14, 4, "vmul", 4) == 0) { 685d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson ExtendNEONArgs(CI, CI->getArgOperand(0), CI->getArgOperand(1), V0, V1); 686d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson NewI = BinaryOperator::CreateMul(V0, V1,"upgraded."+CI->getName(),CI); 687d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson } else if (Name.compare(14, 4, "vmla", 4) == 0) { 688d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson ExtendNEONArgs(CI, CI->getArgOperand(1), CI->getArgOperand(2), V0, V1); 689d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson Instruction *MulI = BinaryOperator::CreateMul(V0, V1, "", CI); 690d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson NewI = BinaryOperator::CreateAdd(CI->getArgOperand(0), MulI, 691d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson "upgraded."+CI->getName(), CI); 692d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson } else if (Name.compare(14, 4, "vmls", 4) == 0) { 693d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson ExtendNEONArgs(CI, CI->getArgOperand(1), CI->getArgOperand(2), V0, V1); 694d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson Instruction *MulI = BinaryOperator::CreateMul(V0, V1, "", CI); 695d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson NewI = BinaryOperator::CreateSub(CI->getArgOperand(0), MulI, 696d0b69cf1198dadbb7bdfc385334b67f60f756539Bob Wilson "upgraded."+CI->getName(), CI); 697eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson } else if (Name.compare(14, 4, "vabd", 4) == 0) { 698eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson NewI = CallVABD(CI, CI->getArgOperand(0), CI->getArgOperand(1)); 699eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson NewI = new ZExtInst(NewI, CI->getType(), "upgraded."+CI->getName(), CI); 700eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson } else if (Name.compare(14, 4, "vaba", 4) == 0) { 701eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson NewI = CallVABD(CI, CI->getArgOperand(1), CI->getArgOperand(2)); 702eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson if (Name.at(18) == 'l') 703eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson NewI = new ZExtInst(NewI, CI->getType(), "", CI); 704eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson NewI = BinaryOperator::CreateAdd(CI->getArgOperand(0), NewI, 705eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson "upgraded."+CI->getName(), CI); 706973a074345add36c046c0f0bfea0156a532ab479Bob Wilson } else if (Name.compare(14, 6, "vmovn.", 6) == 0) { 707973a074345add36c046c0f0bfea0156a532ab479Bob Wilson NewI = new TruncInst(CI->getArgOperand(0), CI->getType(), 708973a074345add36c046c0f0bfea0156a532ab479Bob Wilson "upgraded." + CI->getName(), CI); 709b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson } else { 710b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson llvm_unreachable("Unknown arm.neon function for CallInst upgrade."); 711b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson } 712b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson // Replace any uses of the old CallInst. 713b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson if (!CI->use_empty()) 714b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson CI->replaceAllUsesWith(NewI); 715b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson CI->eraseFromParent(); 716b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson return; 717b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson } 718b31a11b466281b7e01cfde007b2041eefa2341e4Bob Wilson 7194797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng bool isLoadH = false, isLoadL = false, isMovL = false; 720e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng bool isMovSD = false, isShufPD = false; 721e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng bool isUnpckhPD = false, isUnpcklPD = false; 722a31593901de573813d1d8e7884a152011641a713Evan Cheng bool isPunpckhQPD = false, isPunpcklQPD = false; 72303d7651c3652e1f0cc86e79b26585d86818da9cfDaniel Dunbar if (F->getName() == "llvm.x86.sse2.loadh.pd") 7244797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng isLoadH = true; 72503d7651c3652e1f0cc86e79b26585d86818da9cfDaniel Dunbar else if (F->getName() == "llvm.x86.sse2.loadl.pd") 7264797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng isLoadL = true; 72703d7651c3652e1f0cc86e79b26585d86818da9cfDaniel Dunbar else if (F->getName() == "llvm.x86.sse2.movl.dq") 7284797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng isMovL = true; 72903d7651c3652e1f0cc86e79b26585d86818da9cfDaniel Dunbar else if (F->getName() == "llvm.x86.sse2.movs.d") 730e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng isMovSD = true; 73103d7651c3652e1f0cc86e79b26585d86818da9cfDaniel Dunbar else if (F->getName() == "llvm.x86.sse2.shuf.pd") 732e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng isShufPD = true; 73303d7651c3652e1f0cc86e79b26585d86818da9cfDaniel Dunbar else if (F->getName() == "llvm.x86.sse2.unpckh.pd") 734e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng isUnpckhPD = true; 73503d7651c3652e1f0cc86e79b26585d86818da9cfDaniel Dunbar else if (F->getName() == "llvm.x86.sse2.unpckl.pd") 736e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng isUnpcklPD = true; 73703d7651c3652e1f0cc86e79b26585d86818da9cfDaniel Dunbar else if (F->getName() == "llvm.x86.sse2.punpckh.qdq") 738a31593901de573813d1d8e7884a152011641a713Evan Cheng isPunpckhQPD = true; 73903d7651c3652e1f0cc86e79b26585d86818da9cfDaniel Dunbar else if (F->getName() == "llvm.x86.sse2.punpckl.qdq") 740a31593901de573813d1d8e7884a152011641a713Evan Cheng isPunpcklQPD = true; 7414797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng 742e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng if (isLoadH || isLoadL || isMovL || isMovSD || isShufPD || 743a31593901de573813d1d8e7884a152011641a713Evan Cheng isUnpckhPD || isUnpcklPD || isPunpckhQPD || isPunpcklQPD) { 744f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng std::vector<Constant*> Idxs; 745f2937ac4eddb5ced78a1d73206de020c6d9e440fGabor Greif Value *Op0 = CI->getArgOperand(0); 746e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng ShuffleVectorInst *SI = NULL; 7474797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng if (isLoadH || isLoadL) { 7489e9a0d5fc26878e51a58a8b57900fcbf952c2691Owen Anderson Value *Op1 = UndefValue::get(Op0->getType()); 749f2937ac4eddb5ced78a1d73206de020c6d9e440fGabor Greif Value *Addr = new BitCastInst(CI->getArgOperand(1), 750ac53a0b272452013124bfc70480aea5e41b60f40Duncan Sands Type::getDoublePtrTy(C), 7514797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng "upgraded.", CI); 7524797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng Value *Load = new LoadInst(Addr, "upgraded.", false, 8, CI); 7531d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Value *Idx = ConstantInt::get(Type::getInt32Ty(C), 0); 7544797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng Op1 = InsertElementInst::Create(Op1, Load, Idx, "upgraded.", CI); 7554797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng 7564797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng if (isLoadH) { 7571d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 0)); 7581d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 2)); 7594797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng } else { 7601d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 2)); 7611d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 1)); 7624797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng } 763af7ec975870f92245f1f1484ac80a1e2db6a0afaOwen Anderson Value *Mask = ConstantVector::get(Idxs); 7644797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng SI = new ShuffleVectorInst(Op0, Op1, Mask, "upgraded.", CI); 765e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng } else if (isMovL) { 7661d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Constant *Zero = ConstantInt::get(Type::getInt32Ty(C), 0); 7674797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng Idxs.push_back(Zero); 7684797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng Idxs.push_back(Zero); 7694797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng Idxs.push_back(Zero); 7704797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng Idxs.push_back(Zero); 771af7ec975870f92245f1f1484ac80a1e2db6a0afaOwen Anderson Value *ZeroV = ConstantVector::get(Idxs); 772f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng 7734797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng Idxs.clear(); 7741d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 4)); 7751d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 5)); 7761d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 2)); 7771d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 3)); 778af7ec975870f92245f1f1484ac80a1e2db6a0afaOwen Anderson Value *Mask = ConstantVector::get(Idxs); 7794797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng SI = new ShuffleVectorInst(ZeroV, Op0, Mask, "upgraded.", CI); 780a31593901de573813d1d8e7884a152011641a713Evan Cheng } else if (isMovSD || 781a31593901de573813d1d8e7884a152011641a713Evan Cheng isUnpckhPD || isUnpcklPD || isPunpckhQPD || isPunpcklQPD) { 782f2937ac4eddb5ced78a1d73206de020c6d9e440fGabor Greif Value *Op1 = CI->getArgOperand(1); 783e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng if (isMovSD) { 7841d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 2)); 7851d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 1)); 786a31593901de573813d1d8e7884a152011641a713Evan Cheng } else if (isUnpckhPD || isPunpckhQPD) { 7871d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 1)); 7881d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 3)); 789e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng } else { 7901d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 0)); 7911d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 2)); 792e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng } 793af7ec975870f92245f1f1484ac80a1e2db6a0afaOwen Anderson Value *Mask = ConstantVector::get(Idxs); 794e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng SI = new ShuffleVectorInst(Op0, Op1, Mask, "upgraded.", CI); 795e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng } else if (isShufPD) { 796f2937ac4eddb5ced78a1d73206de020c6d9e440fGabor Greif Value *Op1 = CI->getArgOperand(1); 797a399781289092fcdceb58b21174229f4373c4191Gabor Greif unsigned MaskVal = 798a399781289092fcdceb58b21174229f4373c4191Gabor Greif cast<ConstantInt>(CI->getArgOperand(2))->getZExtValue(); 7991d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), MaskVal & 1)); 8001d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 801f81b57694b3c34a79b1464ffd21e6768c8d22662Owen Anderson ((MaskVal >> 1) & 1)+2)); 802af7ec975870f92245f1f1484ac80a1e2db6a0afaOwen Anderson Value *Mask = ConstantVector::get(Idxs); 803e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng SI = new ShuffleVectorInst(Op0, Op1, Mask, "upgraded.", CI); 8044797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng } 805f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng 806e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng assert(SI && "Unexpected!"); 807e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng 808f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng // Handle any uses of the old CallInst. 809f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng if (!CI->use_empty()) 810f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng // Replace all uses of the old call with the new cast which has the 811f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng // correct type. 812f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng CI->replaceAllUsesWith(SI); 813f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng 814f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng // Clean up the old call now that it has been completely upgraded. 815f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng CI->eraseFromParent(); 8168258d0b4bfd5fe40c29fa19e24c23ba3ac157e23Eric Christopher } else if (F->getName() == "llvm.x86.sse41.pmulld") { 8178258d0b4bfd5fe40c29fa19e24c23ba3ac157e23Eric Christopher // Upgrade this set of intrinsics into vector multiplies. 818f2937ac4eddb5ced78a1d73206de020c6d9e440fGabor Greif Instruction *Mul = BinaryOperator::CreateMul(CI->getArgOperand(0), 819f2937ac4eddb5ced78a1d73206de020c6d9e440fGabor Greif CI->getArgOperand(1), 8208258d0b4bfd5fe40c29fa19e24c23ba3ac157e23Eric Christopher CI->getName(), 8218258d0b4bfd5fe40c29fa19e24c23ba3ac157e23Eric Christopher CI); 8228258d0b4bfd5fe40c29fa19e24c23ba3ac157e23Eric Christopher // Fix up all the uses with our new multiply. 8238258d0b4bfd5fe40c29fa19e24c23ba3ac157e23Eric Christopher if (!CI->use_empty()) 8248258d0b4bfd5fe40c29fa19e24c23ba3ac157e23Eric Christopher CI->replaceAllUsesWith(Mul); 8258258d0b4bfd5fe40c29fa19e24c23ba3ac157e23Eric Christopher 8268258d0b4bfd5fe40c29fa19e24c23ba3ac157e23Eric Christopher // Remove upgraded multiply. 8278258d0b4bfd5fe40c29fa19e24c23ba3ac157e23Eric Christopher CI->eraseFromParent(); 8286d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher } else if (F->getName() == "llvm.x86.ssse3.palign.r") { 829cfbb7d43299a2ce94b83ced4a1cbcfe69e387b52Gabor Greif Value *Op1 = CI->getArgOperand(0); 830cfbb7d43299a2ce94b83ced4a1cbcfe69e387b52Gabor Greif Value *Op2 = CI->getArgOperand(1); 831cfbb7d43299a2ce94b83ced4a1cbcfe69e387b52Gabor Greif Value *Op3 = CI->getArgOperand(2); 8326d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher unsigned shiftVal = cast<ConstantInt>(Op3)->getZExtValue(); 8336d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Value *Rep; 8346d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher IRBuilder<> Builder(C); 8356d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Builder.SetInsertPoint(CI->getParent(), CI); 8366d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 8376d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // If palignr is shifting the pair of input vectors less than 9 bytes, 8386d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // emit a shuffle instruction. 8396d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher if (shiftVal <= 8) { 8406d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher const Type *IntTy = Type::getInt32Ty(C); 8416d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher const Type *EltTy = Type::getInt8Ty(C); 8426d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher const Type *VecTy = VectorType::get(EltTy, 8); 8436d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 8446d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Op2 = Builder.CreateBitCast(Op2, VecTy); 8456d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Op1 = Builder.CreateBitCast(Op1, VecTy); 8466d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 8476d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher llvm::SmallVector<llvm::Constant*, 8> Indices; 8486d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher for (unsigned i = 0; i != 8; ++i) 8496d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Indices.push_back(ConstantInt::get(IntTy, shiftVal + i)); 8506d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 8516d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Value *SV = ConstantVector::get(Indices.begin(), Indices.size()); 8526d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Rep = Builder.CreateShuffleVector(Op2, Op1, SV, "palignr"); 8536d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Rep = Builder.CreateBitCast(Rep, F->getReturnType()); 8546d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher } 8556d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 8566d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // If palignr is shifting the pair of input vectors more than 8 but less 8576d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // than 16 bytes, emit a logical right shift of the destination. 8586d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher else if (shiftVal < 16) { 8596d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // MMX has these as 1 x i64 vectors for some odd optimization reasons. 8606d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher const Type *EltTy = Type::getInt64Ty(C); 8616d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher const Type *VecTy = VectorType::get(EltTy, 1); 8626d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 8636d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Op1 = Builder.CreateBitCast(Op1, VecTy, "cast"); 8646d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Op2 = ConstantInt::get(VecTy, (shiftVal-8) * 8); 8656d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 8666d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // create i32 constant 8676d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Function *I = 8686d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Intrinsic::getDeclaration(F->getParent(), Intrinsic::x86_mmx_psrl_q); 8696d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Rep = Builder.CreateCall2(I, Op1, Op2, "palignr"); 8706d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher } 8716d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 8726d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // If palignr is shifting the pair of vectors more than 32 bytes, emit zero. 8736d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher else { 8746d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Rep = Constant::getNullValue(F->getReturnType()); 8756d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher } 8766d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 8776d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // Replace any uses with our new instruction. 8786d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher if (!CI->use_empty()) 8796d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher CI->replaceAllUsesWith(Rep); 8806d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 8816d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // Remove upgraded instruction. 8826d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher CI->eraseFromParent(); 8836d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 8846d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher } else if (F->getName() == "llvm.x86.ssse3.palign.r.128") { 885cfbb7d43299a2ce94b83ced4a1cbcfe69e387b52Gabor Greif Value *Op1 = CI->getArgOperand(0); 886cfbb7d43299a2ce94b83ced4a1cbcfe69e387b52Gabor Greif Value *Op2 = CI->getArgOperand(1); 887cfbb7d43299a2ce94b83ced4a1cbcfe69e387b52Gabor Greif Value *Op3 = CI->getArgOperand(2); 8886d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher unsigned shiftVal = cast<ConstantInt>(Op3)->getZExtValue(); 8896d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Value *Rep; 8906d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher IRBuilder<> Builder(C); 8916d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Builder.SetInsertPoint(CI->getParent(), CI); 8926d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 8936d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // If palignr is shifting the pair of input vectors less than 17 bytes, 8946d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // emit a shuffle instruction. 8956d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher if (shiftVal <= 16) { 8966d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher const Type *IntTy = Type::getInt32Ty(C); 8976d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher const Type *EltTy = Type::getInt8Ty(C); 8986d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher const Type *VecTy = VectorType::get(EltTy, 16); 8996d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 9006d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Op2 = Builder.CreateBitCast(Op2, VecTy); 9016d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Op1 = Builder.CreateBitCast(Op1, VecTy); 9026d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 9036d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher llvm::SmallVector<llvm::Constant*, 16> Indices; 9046d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher for (unsigned i = 0; i != 16; ++i) 9056d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Indices.push_back(ConstantInt::get(IntTy, shiftVal + i)); 9066d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 9076d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Value *SV = ConstantVector::get(Indices.begin(), Indices.size()); 9086d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Rep = Builder.CreateShuffleVector(Op2, Op1, SV, "palignr"); 9096d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Rep = Builder.CreateBitCast(Rep, F->getReturnType()); 9106d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher } 9116d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 9126d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // If palignr is shifting the pair of input vectors more than 16 but less 9136d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // than 32 bytes, emit a logical right shift of the destination. 9146d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher else if (shiftVal < 32) { 9156d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher const Type *EltTy = Type::getInt64Ty(C); 9166d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher const Type *VecTy = VectorType::get(EltTy, 2); 9176d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher const Type *IntTy = Type::getInt32Ty(C); 9186d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 9196d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Op1 = Builder.CreateBitCast(Op1, VecTy, "cast"); 9206d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Op2 = ConstantInt::get(IntTy, (shiftVal-16) * 8); 9216d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 9226d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // create i32 constant 9236d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Function *I = 9246d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Intrinsic::getDeclaration(F->getParent(), Intrinsic::x86_sse2_psrl_dq); 9256d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Rep = Builder.CreateCall2(I, Op1, Op2, "palignr"); 9266d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher } 9276d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 9286d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // If palignr is shifting the pair of vectors more than 32 bytes, emit zero. 9296d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher else { 9306d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Rep = Constant::getNullValue(F->getReturnType()); 9316d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher } 9326d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 9336d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // Replace any uses with our new instruction. 9346d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher if (!CI->use_empty()) 9356d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher CI->replaceAllUsesWith(Rep); 9366d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 9376d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // Remove upgraded instruction. 9386d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher CI->eraseFromParent(); 9396d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 940a5cecd0a130f7ebc4787f8f5b3e8959e41786673Evan Cheng } else { 941c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable("Unknown function for CallInst upgrade."); 942f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng } 943f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng return; 944f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng } 945f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng 946051a950000e21935165db56695e35bade668193bGabor Greif switch (NewFn->getIntrinsicID()) { 947eb0c3d372906df9c61a31651a0ba278034447e94Bob Wilson default: llvm_unreachable("Unknown function for CallInst upgrade."); 9487a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson case Intrinsic::arm_neon_vld1: 9497a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson case Intrinsic::arm_neon_vld2: 9507a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson case Intrinsic::arm_neon_vld3: 9517a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson case Intrinsic::arm_neon_vld4: 9527a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson case Intrinsic::arm_neon_vst1: 9537a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson case Intrinsic::arm_neon_vst2: 9547a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson case Intrinsic::arm_neon_vst3: 9557a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson case Intrinsic::arm_neon_vst4: 9567a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson case Intrinsic::arm_neon_vld2lane: 9577a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson case Intrinsic::arm_neon_vld3lane: 9587a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson case Intrinsic::arm_neon_vld4lane: 9597a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson case Intrinsic::arm_neon_vst2lane: 9607a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson case Intrinsic::arm_neon_vst3lane: 9617a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson case Intrinsic::arm_neon_vst4lane: { 9627a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson // Add a default alignment argument of 1. 9637a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson SmallVector<Value*, 8> Operands(CS.arg_begin(), CS.arg_end()); 9647a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson Operands.push_back(ConstantInt::get(Type::getInt32Ty(C), 1)); 9657a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson CallInst *NewCI = CallInst::Create(NewFn, Operands.begin(), Operands.end(), 9667a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson CI->getName(), CI); 9677a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson NewCI->setTailCall(CI->isTailCall()); 9687a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson NewCI->setCallingConv(CI->getCallingConv()); 9697a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson 9707a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson // Handle any uses of the old CallInst. 9717a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson if (!CI->use_empty()) 9727a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson // Replace all uses of the old call with the new cast which has the 9737a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson // correct type. 9747a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson CI->replaceAllUsesWith(NewCI); 9757a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson 9767a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson // Clean up the old call now that it has been completely upgraded. 9777a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson CI->eraseFromParent(); 9787a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson break; 9797a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson } 9807a9ef44b3b4ddd2dd9a7f92fc8b46c5e5bed6a81Bob Wilson 9810488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_padd_b: 9820488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_padd_w: 9830488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_padd_d: 9840488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_padd_q: 9850488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_padds_b: 9860488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_padds_w: 9870488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_paddus_b: 9880488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_paddus_w: 9890488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_psub_b: 9900488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_psub_w: 9910488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_psub_d: 9920488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_psub_q: 9930488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_psubs_b: 9940488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_psubs_w: 9950488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_psubus_b: 9960488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_psubus_w: 9970488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_pmulh_w: 9980488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_pmull_w: 9990488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_pmulhu_w: 10000488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_pmulu_dq: 10010488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_pmadd_wd: 10020488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_pand: 10030488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_pandn: 10040488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_por: 10050488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_pxor: 10060488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_pavg_b: 10070488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_pavg_w: 10080488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_pmaxu_b: 10090488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_pmaxs_w: 10100488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_pminu_b: 10110488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_pmins_w: 10120488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_psad_bw: 10130488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_psll_w: 1014d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson case Intrinsic::x86_mmx_psll_d: 1015d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson case Intrinsic::x86_mmx_psll_q: 10160488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_pslli_w: 10170488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_pslli_d: 10180488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_pslli_q: 10190488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_psrl_w: 1020d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson case Intrinsic::x86_mmx_psrl_d: 1021d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson case Intrinsic::x86_mmx_psrl_q: 10220488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_psrli_w: 10230488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_psrli_d: 10240488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_psrli_q: 10250488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_psra_w: 10260488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_psra_d: 10270488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_psrai_w: 10280488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_psrai_d: 10290488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_packsswb: 10300488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_packssdw: 10310488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_packuswb: 10320488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_punpckhbw: 10330488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_punpckhwd: 10340488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_punpckhdq: 10350488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_punpcklbw: 10360488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_punpcklwd: 10370488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_punpckldq: 10380488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_pcmpeq_b: 10390488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_pcmpeq_w: 10400488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_pcmpeq_d: 10410488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_pcmpgt_b: 10420488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_pcmpgt_w: 10430488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_pcmpgt_d: { 104458d74910c6b82e622ecbb57d6644d48fec5a5c0fChris Lattner Value *Operands[2]; 1045d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson 10460488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen // Cast the operand to the X86 MMX type. 10470488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Operands[0] = new BitCastInst(CI->getArgOperand(0), 10480488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen NewFn->getFunctionType()->getParamType(0), 10490488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen "upgraded.", CI); 10500488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 10510488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen switch (NewFn->getIntrinsicID()) { 10520488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen default: 10530488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen // Cast to the X86 MMX type. 10540488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Operands[1] = new BitCastInst(CI->getArgOperand(1), 10550488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen NewFn->getFunctionType()->getParamType(1), 10560488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen "upgraded.", CI); 10570488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen break; 10580488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_pslli_w: 10590488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_pslli_d: 10600488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_pslli_q: 10610488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_psrli_w: 10620488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_psrli_d: 10630488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_psrli_q: 10640488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_psrai_w: 10650488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_psrai_d: 10660488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen // These take an i32 as their second parameter. 10670488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Operands[1] = CI->getArgOperand(1); 10680488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen break; 10690488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen } 10700488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 10710488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen ConstructNewCallInst(NewFn, CI, Operands, 2); 10720488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen break; 10730488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen } 10740488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_maskmovq: { 10750488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Value *Operands[3]; 10760488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 10770488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen // Cast the operands to the X86 MMX type. 10780488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Operands[0] = new BitCastInst(CI->getArgOperand(0), 10790488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen NewFn->getFunctionType()->getParamType(0), 10800488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen "upgraded.", CI); 10810488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Operands[1] = new BitCastInst(CI->getArgOperand(1), 10820488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen NewFn->getFunctionType()->getParamType(1), 10830488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen "upgraded.", CI); 10840488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Operands[2] = CI->getArgOperand(2); 10850488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 10860488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen ConstructNewCallInst(NewFn, CI, Operands, 3, false); 10870488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen break; 10880488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen } 10890488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_pmovmskb: { 10900488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Value *Operands[1]; 10910488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 10920488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen // Cast the operand to the X86 MMX type. 10930488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Operands[0] = new BitCastInst(CI->getArgOperand(0), 10940488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen NewFn->getFunctionType()->getParamType(0), 10950488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen "upgraded.", CI); 10960488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 10970488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen ConstructNewCallInst(NewFn, CI, Operands, 1); 10980488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen break; 10990488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen } 11000488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_movnt_dq: { 11010488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Value *Operands[2]; 11020488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 1103f2937ac4eddb5ced78a1d73206de020c6d9e440fGabor Greif Operands[0] = CI->getArgOperand(0); 11040488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 11050488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen // Cast the operand to the X86 MMX type. 11060488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Operands[1] = new BitCastInst(CI->getArgOperand(1), 11070488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen NewFn->getFunctionType()->getParamType(1), 11080488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen "upgraded.", CI); 11090488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 11100488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen ConstructNewCallInst(NewFn, CI, Operands, 2, false); 1111d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson break; 11120488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen } 11130488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_palignr_b: { 11140488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Value *Operands[3]; 11150488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 11160488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen // Cast the operands to the X86 MMX type. 11170488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Operands[0] = new BitCastInst(CI->getArgOperand(0), 11180488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen NewFn->getFunctionType()->getParamType(0), 11190488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen "upgraded.", CI); 11200488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Operands[1] = new BitCastInst(CI->getArgOperand(1), 11210488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen NewFn->getFunctionType()->getParamType(1), 11220488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen "upgraded.", CI); 11230488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Operands[2] = CI->getArgOperand(2); 11240488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 11250488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen ConstructNewCallInst(NewFn, CI, Operands, 3); 11260488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen break; 11270488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen } 11280488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_pextr_w: { 11290488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Value *Operands[2]; 11300488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 11310488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen // Cast the operands to the X86 MMX type. 11320488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Operands[0] = new BitCastInst(CI->getArgOperand(0), 11330488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen NewFn->getFunctionType()->getParamType(0), 11340488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen "upgraded.", CI); 11350488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Operands[1] = CI->getArgOperand(1); 11360488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 11370488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen ConstructNewCallInst(NewFn, CI, Operands, 2); 11380488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen break; 11390488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen } 11400488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_pinsr_w: { 11410488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Value *Operands[3]; 11420488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 11430488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen // Cast the operands to the X86 MMX type. 11440488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Operands[0] = new BitCastInst(CI->getArgOperand(0), 11450488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen NewFn->getFunctionType()->getParamType(0), 11460488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen "upgraded.", CI); 11470488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Operands[1] = CI->getArgOperand(1); 11480488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Operands[2] = CI->getArgOperand(2); 11490488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 11500488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen ConstructNewCallInst(NewFn, CI, Operands, 3); 11510488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen break; 11520488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen } 11530488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen#if 0 11540488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_cvtsi32_si64: { 11550488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen // The return type needs to be changed. 11560488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Value *Operands[1]; 11570488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Operands[0] = CI->getArgOperand(0); 11580488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen ConstructNewCallInst(NewFn, CI, Operands, 1); 11590488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen break; 11600488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen } 11610488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_cvtsi64_si32: { 11620488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Value *Operands[1]; 11630488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 11640488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen // Cast the operand to the X86 MMX type. 11650488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Operands[0] = new BitCastInst(CI->getArgOperand(0), 11660488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen NewFn->getFunctionType()->getParamType(0), 11670488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen "upgraded.", CI); 11680488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 11690488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen ConstructNewCallInst(NewFn, CI, Operands, 1); 11700488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen break; 11710488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen } 11720488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_vec_init_b: 11730488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_vec_init_w: 11740488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_vec_init_d: { 11750488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen // The return type needs to be changed. 11760488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Value *Operands[8]; 11770488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen unsigned NumOps = 0; 11780488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 11790488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen switch (NewFn->getIntrinsicID()) { 11800488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen default: break; 11810488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_vec_init_b: NumOps = 8; break; 11820488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_vec_init_w: NumOps = 4; break; 11830488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_vec_init_d: NumOps = 2; break; 11840488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen } 11850488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 11860488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen switch (NewFn->getIntrinsicID()) { 11870488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen default: break; 11880488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_vec_init_b: 11890488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Operands[7] = CI->getArgOperand(7); 11900488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Operands[6] = CI->getArgOperand(6); 11910488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Operands[5] = CI->getArgOperand(5); 11920488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Operands[4] = CI->getArgOperand(4); 11930488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen // FALLTHRU 11940488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_vec_init_w: 11950488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Operands[3] = CI->getArgOperand(3); 11960488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Operands[2] = CI->getArgOperand(2); 11970488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen // FALLTHRU 11980488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_vec_init_d: 11990488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Operands[1] = CI->getArgOperand(1); 12000488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Operands[0] = CI->getArgOperand(0); 12010488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen break; 12020488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen } 12030488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 12040488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen ConstructNewCallInst(NewFn, CI, Operands, NumOps); 12050488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen break; 12060488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen } 12070488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen case Intrinsic::x86_mmx_vec_ext_d: { 12080488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Value *Operands[2]; 12090488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 12100488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen // Cast the operand to the X86 MMX type. 12110488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Operands[0] = new BitCastInst(CI->getArgOperand(0), 12120488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen NewFn->getFunctionType()->getParamType(0), 12130488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen "upgraded.", CI); 12140488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen Operands[1] = CI->getArgOperand(1); 12150488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 12160488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen ConstructNewCallInst(NewFn, CI, Operands, 2); 12170488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen break; 12180488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen } 12190488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen#endif 12200488fb649a56b7fc89a5814df5308813f9e5a85dDale Johannesen 12216994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth case Intrinsic::ctlz: 12226994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth case Intrinsic::ctpop: 1223051a950000e21935165db56695e35bade668193bGabor Greif case Intrinsic::cttz: { 1224bb6eabf4f5b518a333ab4cedce910962ff935e3aGabor Greif // Build a small vector of the original arguments. 1225bb6eabf4f5b518a333ab4cedce910962ff935e3aGabor Greif SmallVector<Value*, 8> Operands(CS.arg_begin(), CS.arg_end()); 12266994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 12276994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // Construct a new CallInst 1228051a950000e21935165db56695e35bade668193bGabor Greif CallInst *NewCI = CallInst::Create(NewFn, Operands.begin(), Operands.end(), 1229051a950000e21935165db56695e35bade668193bGabor Greif "upgraded."+CI->getName(), CI); 12306994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth NewCI->setTailCall(CI->isTailCall()); 12316994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth NewCI->setCallingConv(CI->getCallingConv()); 12326994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 12336994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // Handle any uses of the old CallInst. 12346994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth if (!CI->use_empty()) { 12356994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // Check for sign extend parameter attributes on the return values. 12360598866c052147c31b808391f58434ce3dbfb838Devang Patel bool SrcSExt = NewFn->getAttributes().paramHasAttr(0, Attribute::SExt); 12370598866c052147c31b808391f58434ce3dbfb838Devang Patel bool DestSExt = F->getAttributes().paramHasAttr(0, Attribute::SExt); 12386994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 12396994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // Construct an appropriate cast from the new return type to the old. 12407cbd8a3e92221437048b484d5ef9c0a22d0f8c58Gabor Greif CastInst *RetCast = CastInst::Create( 12416994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth CastInst::getCastOpcode(NewCI, SrcSExt, 12426994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth F->getReturnType(), 12436994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth DestSExt), 12446994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth NewCI, F->getReturnType(), 12456994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth NewCI->getName(), CI); 12466994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth NewCI->moveBefore(RetCast); 12476994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 12486994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // Replace all uses of the old call with the new cast which has the 12496994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // correct type. 12506994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth CI->replaceAllUsesWith(RetCast); 12516994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth } 12526994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 12536994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // Clean up the old call now that it has been completely upgraded. 12546994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth CI->eraseFromParent(); 1255051a950000e21935165db56695e35bade668193bGabor Greif } 1256051a950000e21935165db56695e35bade668193bGabor Greif break; 1257b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands case Intrinsic::eh_selector: 1258b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands case Intrinsic::eh_typeid_for: { 1259b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands // Only the return type changed. 1260bb6eabf4f5b518a333ab4cedce910962ff935e3aGabor Greif SmallVector<Value*, 8> Operands(CS.arg_begin(), CS.arg_end()); 1261b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands CallInst *NewCI = CallInst::Create(NewFn, Operands.begin(), Operands.end(), 1262b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands "upgraded." + CI->getName(), CI); 1263b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands NewCI->setTailCall(CI->isTailCall()); 1264b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands NewCI->setCallingConv(CI->getCallingConv()); 1265b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands 1266b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands // Handle any uses of the old CallInst. 1267b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands if (!CI->use_empty()) { 1268b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands // Construct an appropriate cast from the new return type to the old. 1269b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands CastInst *RetCast = 1270b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands CastInst::Create(CastInst::getCastOpcode(NewCI, true, 1271b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands F->getReturnType(), true), 1272b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands NewCI, F->getReturnType(), NewCI->getName(), CI); 1273b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands CI->replaceAllUsesWith(RetCast); 1274b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands } 1275b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands CI->eraseFromParent(); 1276b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands } 1277b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands break; 127820adc9dc4650313f017b27d9818eb2176238113dMon P Wang case Intrinsic::memcpy: 127920adc9dc4650313f017b27d9818eb2176238113dMon P Wang case Intrinsic::memmove: 128020adc9dc4650313f017b27d9818eb2176238113dMon P Wang case Intrinsic::memset: { 128120adc9dc4650313f017b27d9818eb2176238113dMon P Wang // Add isVolatile 128220adc9dc4650313f017b27d9818eb2176238113dMon P Wang const llvm::Type *I1Ty = llvm::Type::getInt1Ty(CI->getContext()); 1283f2937ac4eddb5ced78a1d73206de020c6d9e440fGabor Greif Value *Operands[5] = { CI->getArgOperand(0), CI->getArgOperand(1), 1284f2937ac4eddb5ced78a1d73206de020c6d9e440fGabor Greif CI->getArgOperand(2), CI->getArgOperand(3), 128520adc9dc4650313f017b27d9818eb2176238113dMon P Wang llvm::ConstantInt::get(I1Ty, 0) }; 128620adc9dc4650313f017b27d9818eb2176238113dMon P Wang CallInst *NewCI = CallInst::Create(NewFn, Operands, Operands+5, 128720adc9dc4650313f017b27d9818eb2176238113dMon P Wang CI->getName(), CI); 128820adc9dc4650313f017b27d9818eb2176238113dMon P Wang NewCI->setTailCall(CI->isTailCall()); 128920adc9dc4650313f017b27d9818eb2176238113dMon P Wang NewCI->setCallingConv(CI->getCallingConv()); 129020adc9dc4650313f017b27d9818eb2176238113dMon P Wang // Handle any uses of the old CallInst. 129120adc9dc4650313f017b27d9818eb2176238113dMon P Wang if (!CI->use_empty()) 129220adc9dc4650313f017b27d9818eb2176238113dMon P Wang // Replace all uses of the old call with the new cast which has the 129320adc9dc4650313f017b27d9818eb2176238113dMon P Wang // correct type. 129420adc9dc4650313f017b27d9818eb2176238113dMon P Wang CI->replaceAllUsesWith(NewCI); 129520adc9dc4650313f017b27d9818eb2176238113dMon P Wang 129620adc9dc4650313f017b27d9818eb2176238113dMon P Wang // Clean up the old call now that it has been completely upgraded. 129720adc9dc4650313f017b27d9818eb2176238113dMon P Wang CI->eraseFromParent(); 129820adc9dc4650313f017b27d9818eb2176238113dMon P Wang break; 129920adc9dc4650313f017b27d9818eb2176238113dMon P Wang } 13006994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth } 13016994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth} 13026994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 13036994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth// This tests each Function to determine if it needs upgrading. When we find 13046994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth// one we are interested in, we then upgrade all calls to reflect the new 13056994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth// function. 13066994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruthvoid llvm::UpgradeCallsToIntrinsic(Function* F) { 13076994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth assert(F && "Illegal attempt to upgrade a non-existent intrinsic."); 13086994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 13096994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // Upgrade the function and check if it is a totaly new function. 1310f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng Function* NewFn; 1311f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng if (UpgradeIntrinsicFunction(F, NewFn)) { 13126994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth if (NewFn != F) { 13136994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // Replace all uses to the old function with the new one if necessary. 13146994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth for (Value::use_iterator UI = F->use_begin(), UE = F->use_end(); 13156994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth UI != UE; ) { 13166994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth if (CallInst* CI = dyn_cast<CallInst>(*UI++)) 13176994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth UpgradeIntrinsicCall(CI, NewFn); 13186994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth } 13196994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // Remove old function, no longer used, from the module. 13206994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth F->eraseFromParent(); 13216994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth } 13226994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth } 13236994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth} 1324e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel 1325771150accba7ab3480746a451710ac81f950fac2Victor Hernandez/// This function strips all debug info intrinsics, except for llvm.dbg.declare. 1326771150accba7ab3480746a451710ac81f950fac2Victor Hernandez/// If an llvm.dbg.declare intrinsic is invalid, then this function simply 1327771150accba7ab3480746a451710ac81f950fac2Victor Hernandez/// strips that use. 1328e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patelvoid llvm::CheckDebugInfoIntrinsics(Module *M) { 1329e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel 1330e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel 1331e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel if (Function *FuncStart = M->getFunction("llvm.dbg.func.start")) { 133244a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel while (!FuncStart->use_empty()) { 133344a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel CallInst *CI = cast<CallInst>(FuncStart->use_back()); 133444a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel CI->eraseFromParent(); 1335e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel } 133644a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel FuncStart->eraseFromParent(); 1337e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel } 133844a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel 1339e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel if (Function *StopPoint = M->getFunction("llvm.dbg.stoppoint")) { 134044a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel while (!StopPoint->use_empty()) { 134144a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel CallInst *CI = cast<CallInst>(StopPoint->use_back()); 134244a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel CI->eraseFromParent(); 1343e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel } 134444a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel StopPoint->eraseFromParent(); 1345e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel } 1346e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel 1347e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel if (Function *RegionStart = M->getFunction("llvm.dbg.region.start")) { 134844a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel while (!RegionStart->use_empty()) { 134944a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel CallInst *CI = cast<CallInst>(RegionStart->use_back()); 135044a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel CI->eraseFromParent(); 1351e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel } 135244a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel RegionStart->eraseFromParent(); 1353e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel } 1354e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel 1355e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel if (Function *RegionEnd = M->getFunction("llvm.dbg.region.end")) { 135644a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel while (!RegionEnd->use_empty()) { 135744a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel CallInst *CI = cast<CallInst>(RegionEnd->use_back()); 135844a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel CI->eraseFromParent(); 1359e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel } 136044a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel RegionEnd->eraseFromParent(); 1361e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel } 1362e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel 1363e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel if (Function *Declare = M->getFunction("llvm.dbg.declare")) { 1364e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel if (!Declare->use_empty()) { 1365e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel DbgDeclareInst *DDI = cast<DbgDeclareInst>(Declare->use_back()); 1366f2937ac4eddb5ced78a1d73206de020c6d9e440fGabor Greif if (!isa<MDNode>(DDI->getArgOperand(0)) || 1367f2937ac4eddb5ced78a1d73206de020c6d9e440fGabor Greif !isa<MDNode>(DDI->getArgOperand(1))) { 1368e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel while (!Declare->use_empty()) { 1369e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel CallInst *CI = cast<CallInst>(Declare->use_back()); 1370e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel CI->eraseFromParent(); 1371e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel } 1372e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel Declare->eraseFromParent(); 1373e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel } 1374e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel } 1375e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel } 1376e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel} 1377