AutoUpgrade.cpp revision f2937ac4eddb5ced78a1d73206de020c6d9e440f
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" 21c25e7581b9b8088910da31702d4ca21c4734c6d7Torok Edwin#include "llvm/Support/ErrorHandling.h" 226d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher#include "llvm/Support/IRBuilder.h" 23ae9f3a3b7c915f725aef5a7250e88eaeddda03c6Anton Korobeynikov#include <cstring> 246994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruthusing namespace llvm; 256994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 266994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 27f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Chengstatic bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) { 286994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth assert(F && "Illegal to upgrade a non-existent Function."); 296994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 306994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // Get the Function's name. 316994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth const std::string& Name = F->getName(); 326994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 336994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // Convenience 346994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth const FunctionType *FTy = F->getFunctionType(); 356994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 366994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // Quickly eliminate it, if it's not a candidate. 376994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth if (Name.length() <= 8 || Name[0] != 'l' || Name[1] != 'l' || 386994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth Name[2] != 'v' || Name[3] != 'm' || Name[4] != '.') 39f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng return false; 406994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 416994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth Module *M = F->getParent(); 426994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth switch (Name[5]) { 436994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth default: break; 4428873106309db515d58889a4c4fa3e0a92d1b60eMon P Wang case 'a': 45e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang // This upgrades the llvm.atomic.lcs, llvm.atomic.las, llvm.atomic.lss, 46e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang // and atomics with default address spaces to their new names to their new 47e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang // function name (e.g. llvm.atomic.add.i32 => llvm.atomic.add.i32.p0i32) 48e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang if (Name.compare(5,7,"atomic.",7) == 0) { 4928873106309db515d58889a4c4fa3e0a92d1b60eMon P Wang if (Name.compare(12,3,"lcs",3) == 0) { 5028873106309db515d58889a4c4fa3e0a92d1b60eMon P Wang std::string::size_type delim = Name.find('.',12); 51e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang F->setName("llvm.atomic.cmp.swap" + Name.substr(delim) + 52e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang ".p0" + Name.substr(delim+1)); 5328873106309db515d58889a4c4fa3e0a92d1b60eMon P Wang NewFn = F; 5428873106309db515d58889a4c4fa3e0a92d1b60eMon P Wang return true; 5528873106309db515d58889a4c4fa3e0a92d1b60eMon P Wang } 5628873106309db515d58889a4c4fa3e0a92d1b60eMon P Wang else if (Name.compare(12,3,"las",3) == 0) { 5728873106309db515d58889a4c4fa3e0a92d1b60eMon P Wang std::string::size_type delim = Name.find('.',12); 58e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang F->setName("llvm.atomic.load.add"+Name.substr(delim) 59e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang + ".p0" + Name.substr(delim+1)); 6028873106309db515d58889a4c4fa3e0a92d1b60eMon P Wang NewFn = F; 6128873106309db515d58889a4c4fa3e0a92d1b60eMon P Wang return true; 6228873106309db515d58889a4c4fa3e0a92d1b60eMon P Wang } 6328873106309db515d58889a4c4fa3e0a92d1b60eMon P Wang else if (Name.compare(12,3,"lss",3) == 0) { 6428873106309db515d58889a4c4fa3e0a92d1b60eMon P Wang std::string::size_type delim = Name.find('.',12); 65e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang F->setName("llvm.atomic.load.sub"+Name.substr(delim) 66e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang + ".p0" + Name.substr(delim+1)); 67e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang NewFn = F; 68e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang return true; 69e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang } 70e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang else if (Name.rfind(".p") == std::string::npos) { 71e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang // We don't have an address space qualifier so this has be upgraded 72e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang // to the new name. Copy the type name at the end of the intrinsic 73e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang // and add to it 74e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang std::string::size_type delim = Name.find_last_of('.'); 75e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang assert(delim != std::string::npos && "can not find type"); 76e3b3a7241c01f26613694e53b26b01abf764ddfcMon P Wang F->setName(Name + ".p0" + Name.substr(delim+1)); 7728873106309db515d58889a4c4fa3e0a92d1b60eMon P Wang NewFn = F; 7828873106309db515d58889a4c4fa3e0a92d1b60eMon P Wang return true; 7928873106309db515d58889a4c4fa3e0a92d1b60eMon P Wang } 8028873106309db515d58889a4c4fa3e0a92d1b60eMon P Wang } 8128873106309db515d58889a4c4fa3e0a92d1b60eMon P Wang break; 826994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth case 'b': 836994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // This upgrades the name of the llvm.bswap intrinsic function to only use 846994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // a single type name for overloading. We only care about the old format 856994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // 'llvm.bswap.i*.i*', so check for 'bswap.' and then for there being 866994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // a '.' after 'bswap.' 876994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth if (Name.compare(5,6,"bswap.",6) == 0) { 886994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth std::string::size_type delim = Name.find('.',11); 896994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 906994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth if (delim != std::string::npos) { 916994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // Construct the new name as 'llvm.bswap' + '.i*' 926994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth F->setName(Name.substr(0,10)+Name.substr(delim)); 93f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng NewFn = F; 94f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng return true; 956994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth } 966994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth } 976994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth break; 986994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 996994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth case 'c': 1006994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // We only want to fix the 'llvm.ct*' intrinsics which do not have the 1016994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // correct return type, so we check for the name, and then check if the 1026994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // return type does not match the parameter type. 1036994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth if ( (Name.compare(5,5,"ctpop",5) == 0 || 1046994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth Name.compare(5,4,"ctlz",4) == 0 || 1056994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth Name.compare(5,4,"cttz",4) == 0) && 1066994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth FTy->getReturnType() != FTy->getParamType(0)) { 1076994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // We first need to change the name of the old (bad) intrinsic, because 1086994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // its type is incorrect, but we cannot overload that name. We 1096994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // arbitrarily unique it here allowing us to construct a correctly named 1106994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // and typed function below. 1116994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth F->setName(""); 1126994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 1136994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // Now construct the new intrinsic with the correct name and type. We 1146994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // leave the old function around in order to query its type, whatever it 1156994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // may be, and correctly convert up to the new type. 116f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng NewFn = cast<Function>(M->getOrInsertFunction(Name, 117f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng FTy->getParamType(0), 118f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng FTy->getParamType(0), 119f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng (Type *)0)); 120f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng return true; 1216994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth } 1226994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth break; 1236994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 124b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands case 'e': 125b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands // The old llvm.eh.selector.i32 is equivalent to the new llvm.eh.selector. 126b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands if (Name.compare("llvm.eh.selector.i32") == 0) { 127b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands F->setName("llvm.eh.selector"); 128b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands NewFn = F; 129b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands return true; 130b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands } 131b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands // The old llvm.eh.typeid.for.i32 is equivalent to llvm.eh.typeid.for. 132b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands if (Name.compare("llvm.eh.typeid.for.i32") == 0) { 133b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands F->setName("llvm.eh.typeid.for"); 134b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands NewFn = F; 135b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands return true; 136b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands } 137b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands // Convert the old llvm.eh.selector.i64 to a call to llvm.eh.selector. 138b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands if (Name.compare("llvm.eh.selector.i64") == 0) { 139b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands NewFn = Intrinsic::getDeclaration(M, Intrinsic::eh_selector); 140b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands return true; 141b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands } 142b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands // Convert the old llvm.eh.typeid.for.i64 to a call to llvm.eh.typeid.for. 143b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands if (Name.compare("llvm.eh.typeid.for.i64") == 0) { 144b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands NewFn = Intrinsic::getDeclaration(M, Intrinsic::eh_typeid_for); 145b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands return true; 146b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands } 147b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands break; 148b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands 14920adc9dc4650313f017b27d9818eb2176238113dMon P Wang case 'm': { 15020adc9dc4650313f017b27d9818eb2176238113dMon P Wang // This upgrades the llvm.memcpy, llvm.memmove, and llvm.memset to the 15120adc9dc4650313f017b27d9818eb2176238113dMon P Wang // new format that allows overloading the pointer for different address 15220adc9dc4650313f017b27d9818eb2176238113dMon P Wang // space (e.g., llvm.memcpy.i16 => llvm.memcpy.p0i8.p0i8.i16) 15320adc9dc4650313f017b27d9818eb2176238113dMon P Wang const char* NewFnName = NULL; 15420adc9dc4650313f017b27d9818eb2176238113dMon P Wang if (Name.compare(5,8,"memcpy.i",8) == 0) { 15520adc9dc4650313f017b27d9818eb2176238113dMon P Wang if (Name[13] == '8') 15620adc9dc4650313f017b27d9818eb2176238113dMon P Wang NewFnName = "llvm.memcpy.p0i8.p0i8.i8"; 15720adc9dc4650313f017b27d9818eb2176238113dMon P Wang else if (Name.compare(13,2,"16") == 0) 15820adc9dc4650313f017b27d9818eb2176238113dMon P Wang NewFnName = "llvm.memcpy.p0i8.p0i8.i16"; 15920adc9dc4650313f017b27d9818eb2176238113dMon P Wang else if (Name.compare(13,2,"32") == 0) 16020adc9dc4650313f017b27d9818eb2176238113dMon P Wang NewFnName = "llvm.memcpy.p0i8.p0i8.i32"; 16120adc9dc4650313f017b27d9818eb2176238113dMon P Wang else if (Name.compare(13,2,"64") == 0) 16220adc9dc4650313f017b27d9818eb2176238113dMon P Wang NewFnName = "llvm.memcpy.p0i8.p0i8.i64"; 16320adc9dc4650313f017b27d9818eb2176238113dMon P Wang } else if (Name.compare(5,9,"memmove.i",9) == 0) { 16420adc9dc4650313f017b27d9818eb2176238113dMon P Wang if (Name[14] == '8') 16520adc9dc4650313f017b27d9818eb2176238113dMon P Wang NewFnName = "llvm.memmove.p0i8.p0i8.i8"; 16620adc9dc4650313f017b27d9818eb2176238113dMon P Wang else if (Name.compare(14,2,"16") == 0) 16720adc9dc4650313f017b27d9818eb2176238113dMon P Wang NewFnName = "llvm.memmove.p0i8.p0i8.i16"; 16820adc9dc4650313f017b27d9818eb2176238113dMon P Wang else if (Name.compare(14,2,"32") == 0) 16920adc9dc4650313f017b27d9818eb2176238113dMon P Wang NewFnName = "llvm.memmove.p0i8.p0i8.i32"; 17020adc9dc4650313f017b27d9818eb2176238113dMon P Wang else if (Name.compare(14,2,"64") == 0) 17120adc9dc4650313f017b27d9818eb2176238113dMon P Wang NewFnName = "llvm.memmove.p0i8.p0i8.i64"; 17220adc9dc4650313f017b27d9818eb2176238113dMon P Wang } 17320adc9dc4650313f017b27d9818eb2176238113dMon P Wang else if (Name.compare(5,8,"memset.i",8) == 0) { 17420adc9dc4650313f017b27d9818eb2176238113dMon P Wang if (Name[13] == '8') 17520adc9dc4650313f017b27d9818eb2176238113dMon P Wang NewFnName = "llvm.memset.p0i8.i8"; 17620adc9dc4650313f017b27d9818eb2176238113dMon P Wang else if (Name.compare(13,2,"16") == 0) 17720adc9dc4650313f017b27d9818eb2176238113dMon P Wang NewFnName = "llvm.memset.p0i8.i16"; 17820adc9dc4650313f017b27d9818eb2176238113dMon P Wang else if (Name.compare(13,2,"32") == 0) 17920adc9dc4650313f017b27d9818eb2176238113dMon P Wang NewFnName = "llvm.memset.p0i8.i32"; 18020adc9dc4650313f017b27d9818eb2176238113dMon P Wang else if (Name.compare(13,2,"64") == 0) 18120adc9dc4650313f017b27d9818eb2176238113dMon P Wang NewFnName = "llvm.memset.p0i8.i64"; 18220adc9dc4650313f017b27d9818eb2176238113dMon P Wang } 18320adc9dc4650313f017b27d9818eb2176238113dMon P Wang if (NewFnName) { 18420adc9dc4650313f017b27d9818eb2176238113dMon P Wang const FunctionType *FTy = F->getFunctionType(); 18520adc9dc4650313f017b27d9818eb2176238113dMon P Wang NewFn = cast<Function>(M->getOrInsertFunction(NewFnName, 18620adc9dc4650313f017b27d9818eb2176238113dMon P Wang FTy->getReturnType(), 18720adc9dc4650313f017b27d9818eb2176238113dMon P Wang FTy->getParamType(0), 18820adc9dc4650313f017b27d9818eb2176238113dMon P Wang FTy->getParamType(1), 18920adc9dc4650313f017b27d9818eb2176238113dMon P Wang FTy->getParamType(2), 19020adc9dc4650313f017b27d9818eb2176238113dMon P Wang FTy->getParamType(3), 19120adc9dc4650313f017b27d9818eb2176238113dMon P Wang Type::getInt1Ty(F->getContext()), 19220adc9dc4650313f017b27d9818eb2176238113dMon P Wang (Type *)0)); 19320adc9dc4650313f017b27d9818eb2176238113dMon P Wang return true; 19420adc9dc4650313f017b27d9818eb2176238113dMon P Wang } 19520adc9dc4650313f017b27d9818eb2176238113dMon P Wang break; 19620adc9dc4650313f017b27d9818eb2176238113dMon P Wang } 1976994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth case 'p': 1986994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // This upgrades the llvm.part.select overloaded intrinsic names to only 1996994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // use one type specifier in the name. We only care about the old format 2006994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // 'llvm.part.select.i*.i*', and solve as above with bswap. 2016994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth if (Name.compare(5,12,"part.select.",12) == 0) { 2026994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth std::string::size_type delim = Name.find('.',17); 2036994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 2046994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth if (delim != std::string::npos) { 2056994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // Construct a new name as 'llvm.part.select' + '.i*' 2066994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth F->setName(Name.substr(0,16)+Name.substr(delim)); 207f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng NewFn = F; 208f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng return true; 2096994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth } 2106994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth break; 2116994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth } 2126994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 2136994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // This upgrades the llvm.part.set intrinsics similarly as above, however 2146994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // we care about 'llvm.part.set.i*.i*.i*', but only the first two types 2156994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // must match. There is an additional type specifier after these two 2166994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // matching types that we must retain when upgrading. Thus, we require 2176994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // finding 2 periods, not just one, after the intrinsic name. 2186994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth if (Name.compare(5,9,"part.set.",9) == 0) { 2196994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth std::string::size_type delim = Name.find('.',14); 2206994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 2216994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth if (delim != std::string::npos && 2226994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth Name.find('.',delim+1) != std::string::npos) { 2236994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // Construct a new name as 'llvm.part.select' + '.i*.i*' 2246994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth F->setName(Name.substr(0,13)+Name.substr(delim)); 225f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng NewFn = F; 226f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng return true; 2276994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth } 2286994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth break; 2296994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth } 2306994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 2316994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth break; 232d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson case 'x': 233d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson // This fixes all MMX shift intrinsic instructions to take a 234d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson // v1i64 instead of a v2i32 as the second parameter. 235d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson if (Name.compare(5,10,"x86.mmx.ps",10) == 0 && 236d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson (Name.compare(13,4,"psll", 4) == 0 || 237d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson Name.compare(13,4,"psra", 4) == 0 || 23822b942aa4df824adbd3f6eaede53abe451f616e9Evan Cheng Name.compare(13,4,"psrl", 4) == 0) && Name[17] != 'i') { 239d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson 240f81b57694b3c34a79b1464ffd21e6768c8d22662Owen Anderson const llvm::Type *VT = 2411d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson VectorType::get(IntegerType::get(FTy->getContext(), 64), 1); 242d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson 243d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson // We don't have to do anything if the parameter already has 244d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson // the correct type. 245d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson if (FTy->getParamType(1) == VT) 246d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson break; 247d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson 248d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson // We first need to change the name of the old (bad) intrinsic, because 249d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson // its type is incorrect, but we cannot overload that name. We 250d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson // arbitrarily unique it here allowing us to construct a correctly named 251d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson // and typed function below. 252d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson F->setName(""); 253d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson 254d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson assert(FTy->getNumParams() == 2 && "MMX shift intrinsics take 2 args!"); 255d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson 256d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson // Now construct the new intrinsic with the correct name and type. We 257d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson // leave the old function around in order to query its type, whatever it 258d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson // may be, and correctly convert up to the new type. 259f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng NewFn = cast<Function>(M->getOrInsertFunction(Name, 260f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng FTy->getReturnType(), 261f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng FTy->getParamType(0), 262f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng VT, 263f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng (Type *)0)); 264f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng return true; 2654797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng } else if (Name.compare(5,17,"x86.sse2.loadh.pd",17) == 0 || 2664797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng Name.compare(5,17,"x86.sse2.loadl.pd",17) == 0 || 267e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng Name.compare(5,16,"x86.sse2.movl.dq",16) == 0 || 268e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng Name.compare(5,15,"x86.sse2.movs.d",15) == 0 || 269e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng Name.compare(5,16,"x86.sse2.shuf.pd",16) == 0 || 270e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng Name.compare(5,18,"x86.sse2.unpckh.pd",18) == 0 || 271a31593901de573813d1d8e7884a152011641a713Evan Cheng Name.compare(5,18,"x86.sse2.unpckl.pd",18) == 0 || 272a31593901de573813d1d8e7884a152011641a713Evan Cheng Name.compare(5,20,"x86.sse2.punpckh.qdq",20) == 0 || 273a31593901de573813d1d8e7884a152011641a713Evan Cheng Name.compare(5,20,"x86.sse2.punpckl.qdq",20) == 0) { 2744797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng // Calls to these intrinsics are transformed into ShuffleVector's. 275f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng NewFn = 0; 276f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng return true; 2778258d0b4bfd5fe40c29fa19e24c23ba3ac157e23Eric Christopher } else if (Name.compare(5, 16, "x86.sse41.pmulld", 16) == 0) { 2788258d0b4bfd5fe40c29fa19e24c23ba3ac157e23Eric Christopher // Calls to these intrinsics are transformed into vector multiplies. 2798258d0b4bfd5fe40c29fa19e24c23ba3ac157e23Eric Christopher NewFn = 0; 2808258d0b4bfd5fe40c29fa19e24c23ba3ac157e23Eric Christopher return true; 2816d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher } else if (Name.compare(5, 18, "x86.ssse3.palign.r", 18) == 0 || 2826d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Name.compare(5, 22, "x86.ssse3.palign.r.128", 22) == 0) { 2836d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // Calls to these intrinsics are transformed into vector shuffles, shifts, 2846d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // or 0. 2856d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher NewFn = 0; 2866d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher return true; 287d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson } 288f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng 289d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson break; 2906994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth } 2916994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 2926994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // This may not belong here. This function is effectively being overloaded 2936994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // to both detect an intrinsic which needs upgrading, and to provide the 2946994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // upgraded form of the intrinsic. We should perhaps have two separate 2956994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // functions for this. 296f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng return false; 2976994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth} 2986994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 299f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Chengbool llvm::UpgradeIntrinsicFunction(Function *F, Function *&NewFn) { 300f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng NewFn = 0; 301f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng bool Upgraded = UpgradeIntrinsicFunction1(F, NewFn); 302a3355ffb3d30d19d226bbb75707991c60f236e37Duncan Sands 303a3355ffb3d30d19d226bbb75707991c60f236e37Duncan Sands // Upgrade intrinsic attributes. This does not change the function. 304f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng if (NewFn) 305f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng F = NewFn; 30649de98214b82fefeb8f16efbf8cdd8813a85469bDale Johannesen if (unsigned id = F->getIntrinsicID()) 3070598866c052147c31b808391f58434ce3dbfb838Devang Patel F->setAttributes(Intrinsic::getAttributes((Intrinsic::ID)id)); 308a3355ffb3d30d19d226bbb75707991c60f236e37Duncan Sands return Upgraded; 309a3355ffb3d30d19d226bbb75707991c60f236e37Duncan Sands} 310a3355ffb3d30d19d226bbb75707991c60f236e37Duncan Sands 3116994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth// UpgradeIntrinsicCall - Upgrade a call to an old intrinsic to be a call the 3126994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth// upgraded intrinsic. All argument and return casting must be provided in 3136994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth// order to seamlessly integrate with existing context. 3146994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruthvoid llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { 3156994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth Function *F = CI->getCalledFunction(); 3161d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson LLVMContext &C = CI->getContext(); 317f81b57694b3c34a79b1464ffd21e6768c8d22662Owen Anderson 3186994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth assert(F && "CallInst has no function associated with it."); 319f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng 320f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng if (!NewFn) { 3214797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng bool isLoadH = false, isLoadL = false, isMovL = false; 322e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng bool isMovSD = false, isShufPD = false; 323e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng bool isUnpckhPD = false, isUnpcklPD = false; 324a31593901de573813d1d8e7884a152011641a713Evan Cheng bool isPunpckhQPD = false, isPunpcklQPD = false; 32503d7651c3652e1f0cc86e79b26585d86818da9cfDaniel Dunbar if (F->getName() == "llvm.x86.sse2.loadh.pd") 3264797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng isLoadH = true; 32703d7651c3652e1f0cc86e79b26585d86818da9cfDaniel Dunbar else if (F->getName() == "llvm.x86.sse2.loadl.pd") 3284797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng isLoadL = true; 32903d7651c3652e1f0cc86e79b26585d86818da9cfDaniel Dunbar else if (F->getName() == "llvm.x86.sse2.movl.dq") 3304797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng isMovL = true; 33103d7651c3652e1f0cc86e79b26585d86818da9cfDaniel Dunbar else if (F->getName() == "llvm.x86.sse2.movs.d") 332e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng isMovSD = true; 33303d7651c3652e1f0cc86e79b26585d86818da9cfDaniel Dunbar else if (F->getName() == "llvm.x86.sse2.shuf.pd") 334e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng isShufPD = true; 33503d7651c3652e1f0cc86e79b26585d86818da9cfDaniel Dunbar else if (F->getName() == "llvm.x86.sse2.unpckh.pd") 336e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng isUnpckhPD = true; 33703d7651c3652e1f0cc86e79b26585d86818da9cfDaniel Dunbar else if (F->getName() == "llvm.x86.sse2.unpckl.pd") 338e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng isUnpcklPD = true; 33903d7651c3652e1f0cc86e79b26585d86818da9cfDaniel Dunbar else if (F->getName() == "llvm.x86.sse2.punpckh.qdq") 340a31593901de573813d1d8e7884a152011641a713Evan Cheng isPunpckhQPD = true; 34103d7651c3652e1f0cc86e79b26585d86818da9cfDaniel Dunbar else if (F->getName() == "llvm.x86.sse2.punpckl.qdq") 342a31593901de573813d1d8e7884a152011641a713Evan Cheng isPunpcklQPD = true; 3434797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng 344e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng if (isLoadH || isLoadL || isMovL || isMovSD || isShufPD || 345a31593901de573813d1d8e7884a152011641a713Evan Cheng isUnpckhPD || isUnpcklPD || isPunpckhQPD || isPunpcklQPD) { 346f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng std::vector<Constant*> Idxs; 347f2937ac4eddb5ced78a1d73206de020c6d9e440fGabor Greif Value *Op0 = CI->getArgOperand(0); 348e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng ShuffleVectorInst *SI = NULL; 3494797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng if (isLoadH || isLoadL) { 3509e9a0d5fc26878e51a58a8b57900fcbf952c2691Owen Anderson Value *Op1 = UndefValue::get(Op0->getType()); 351f2937ac4eddb5ced78a1d73206de020c6d9e440fGabor Greif Value *Addr = new BitCastInst(CI->getArgOperand(1), 352ac53a0b272452013124bfc70480aea5e41b60f40Duncan Sands Type::getDoublePtrTy(C), 3534797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng "upgraded.", CI); 3544797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng Value *Load = new LoadInst(Addr, "upgraded.", false, 8, CI); 3551d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Value *Idx = ConstantInt::get(Type::getInt32Ty(C), 0); 3564797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng Op1 = InsertElementInst::Create(Op1, Load, Idx, "upgraded.", CI); 3574797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng 3584797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng if (isLoadH) { 3591d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 0)); 3601d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 2)); 3614797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng } else { 3621d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 2)); 3631d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 1)); 3644797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng } 365af7ec975870f92245f1f1484ac80a1e2db6a0afaOwen Anderson Value *Mask = ConstantVector::get(Idxs); 3664797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng SI = new ShuffleVectorInst(Op0, Op1, Mask, "upgraded.", CI); 367e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng } else if (isMovL) { 3681d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Constant *Zero = ConstantInt::get(Type::getInt32Ty(C), 0); 3694797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng Idxs.push_back(Zero); 3704797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng Idxs.push_back(Zero); 3714797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng Idxs.push_back(Zero); 3724797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng Idxs.push_back(Zero); 373af7ec975870f92245f1f1484ac80a1e2db6a0afaOwen Anderson Value *ZeroV = ConstantVector::get(Idxs); 374f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng 3754797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng Idxs.clear(); 3761d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 4)); 3771d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 5)); 3781d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 2)); 3791d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 3)); 380af7ec975870f92245f1f1484ac80a1e2db6a0afaOwen Anderson Value *Mask = ConstantVector::get(Idxs); 3814797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng SI = new ShuffleVectorInst(ZeroV, Op0, Mask, "upgraded.", CI); 382a31593901de573813d1d8e7884a152011641a713Evan Cheng } else if (isMovSD || 383a31593901de573813d1d8e7884a152011641a713Evan Cheng isUnpckhPD || isUnpcklPD || isPunpckhQPD || isPunpcklQPD) { 384f2937ac4eddb5ced78a1d73206de020c6d9e440fGabor Greif Value *Op1 = CI->getArgOperand(1); 385e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng if (isMovSD) { 3861d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 2)); 3871d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 1)); 388a31593901de573813d1d8e7884a152011641a713Evan Cheng } else if (isUnpckhPD || isPunpckhQPD) { 3891d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 1)); 3901d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 3)); 391e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng } else { 3921d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 0)); 3931d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 2)); 394e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng } 395af7ec975870f92245f1f1484ac80a1e2db6a0afaOwen Anderson Value *Mask = ConstantVector::get(Idxs); 396e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng SI = new ShuffleVectorInst(Op0, Op1, Mask, "upgraded.", CI); 397e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng } else if (isShufPD) { 398f2937ac4eddb5ced78a1d73206de020c6d9e440fGabor Greif Value *Op1 = CI->getArgOperand(1); 399f2937ac4eddb5ced78a1d73206de020c6d9e440fGabor Greif unsigned MaskVal = cast<ConstantInt>(CI->getArgOperand(2))->getZExtValue(); 4001d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), MaskVal & 1)); 4011d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson Idxs.push_back(ConstantInt::get(Type::getInt32Ty(C), 402f81b57694b3c34a79b1464ffd21e6768c8d22662Owen Anderson ((MaskVal >> 1) & 1)+2)); 403af7ec975870f92245f1f1484ac80a1e2db6a0afaOwen Anderson Value *Mask = ConstantVector::get(Idxs); 404e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng SI = new ShuffleVectorInst(Op0, Op1, Mask, "upgraded.", CI); 4054797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng } 406f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng 407e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng assert(SI && "Unexpected!"); 408e716bb1c59fe64c663d1d352e0e3889a28dbaca2Evan Cheng 409f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng // Handle any uses of the old CallInst. 410f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng if (!CI->use_empty()) 411f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng // Replace all uses of the old call with the new cast which has the 412f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng // correct type. 413f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng CI->replaceAllUsesWith(SI); 414f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng 415f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng // Clean up the old call now that it has been completely upgraded. 416f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng CI->eraseFromParent(); 4178258d0b4bfd5fe40c29fa19e24c23ba3ac157e23Eric Christopher } else if (F->getName() == "llvm.x86.sse41.pmulld") { 4188258d0b4bfd5fe40c29fa19e24c23ba3ac157e23Eric Christopher // Upgrade this set of intrinsics into vector multiplies. 419f2937ac4eddb5ced78a1d73206de020c6d9e440fGabor Greif Instruction *Mul = BinaryOperator::CreateMul(CI->getArgOperand(0), 420f2937ac4eddb5ced78a1d73206de020c6d9e440fGabor Greif CI->getArgOperand(1), 4218258d0b4bfd5fe40c29fa19e24c23ba3ac157e23Eric Christopher CI->getName(), 4228258d0b4bfd5fe40c29fa19e24c23ba3ac157e23Eric Christopher CI); 4238258d0b4bfd5fe40c29fa19e24c23ba3ac157e23Eric Christopher // Fix up all the uses with our new multiply. 4248258d0b4bfd5fe40c29fa19e24c23ba3ac157e23Eric Christopher if (!CI->use_empty()) 4258258d0b4bfd5fe40c29fa19e24c23ba3ac157e23Eric Christopher CI->replaceAllUsesWith(Mul); 4268258d0b4bfd5fe40c29fa19e24c23ba3ac157e23Eric Christopher 4278258d0b4bfd5fe40c29fa19e24c23ba3ac157e23Eric Christopher // Remove upgraded multiply. 4288258d0b4bfd5fe40c29fa19e24c23ba3ac157e23Eric Christopher CI->eraseFromParent(); 4296d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher } else if (F->getName() == "llvm.x86.ssse3.palign.r") { 4306d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Value *Op1 = CI->getOperand(1); 4316d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Value *Op2 = CI->getOperand(2); 4326d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Value *Op3 = CI->getOperand(3); 4336d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher unsigned shiftVal = cast<ConstantInt>(Op3)->getZExtValue(); 4346d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Value *Rep; 4356d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher IRBuilder<> Builder(C); 4366d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Builder.SetInsertPoint(CI->getParent(), CI); 4376d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 4386d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // If palignr is shifting the pair of input vectors less than 9 bytes, 4396d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // emit a shuffle instruction. 4406d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher if (shiftVal <= 8) { 4416d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher const Type *IntTy = Type::getInt32Ty(C); 4426d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher const Type *EltTy = Type::getInt8Ty(C); 4436d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher const Type *VecTy = VectorType::get(EltTy, 8); 4446d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 4456d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Op2 = Builder.CreateBitCast(Op2, VecTy); 4466d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Op1 = Builder.CreateBitCast(Op1, VecTy); 4476d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 4486d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher llvm::SmallVector<llvm::Constant*, 8> Indices; 4496d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher for (unsigned i = 0; i != 8; ++i) 4506d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Indices.push_back(ConstantInt::get(IntTy, shiftVal + i)); 4516d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 4526d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Value *SV = ConstantVector::get(Indices.begin(), Indices.size()); 4536d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Rep = Builder.CreateShuffleVector(Op2, Op1, SV, "palignr"); 4546d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Rep = Builder.CreateBitCast(Rep, F->getReturnType()); 4556d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher } 4566d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 4576d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // If palignr is shifting the pair of input vectors more than 8 but less 4586d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // than 16 bytes, emit a logical right shift of the destination. 4596d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher else if (shiftVal < 16) { 4606d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // MMX has these as 1 x i64 vectors for some odd optimization reasons. 4616d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher const Type *EltTy = Type::getInt64Ty(C); 4626d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher const Type *VecTy = VectorType::get(EltTy, 1); 4636d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 4646d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Op1 = Builder.CreateBitCast(Op1, VecTy, "cast"); 4656d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Op2 = ConstantInt::get(VecTy, (shiftVal-8) * 8); 4666d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 4676d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // create i32 constant 4686d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Function *I = 4696d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Intrinsic::getDeclaration(F->getParent(), Intrinsic::x86_mmx_psrl_q); 4706d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Rep = Builder.CreateCall2(I, Op1, Op2, "palignr"); 4716d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher } 4726d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 4736d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // If palignr is shifting the pair of vectors more than 32 bytes, emit zero. 4746d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher else { 4756d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Rep = Constant::getNullValue(F->getReturnType()); 4766d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher } 4776d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 4786d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // Replace any uses with our new instruction. 4796d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher if (!CI->use_empty()) 4806d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher CI->replaceAllUsesWith(Rep); 4816d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 4826d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // Remove upgraded instruction. 4836d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher CI->eraseFromParent(); 4846d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 4856d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher } else if (F->getName() == "llvm.x86.ssse3.palign.r.128") { 4866d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Value *Op1 = CI->getOperand(1); 4876d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Value *Op2 = CI->getOperand(2); 4886d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Value *Op3 = CI->getOperand(3); 4896d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher unsigned shiftVal = cast<ConstantInt>(Op3)->getZExtValue(); 4906d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Value *Rep; 4916d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher IRBuilder<> Builder(C); 4926d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Builder.SetInsertPoint(CI->getParent(), CI); 4936d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 4946d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // If palignr is shifting the pair of input vectors less than 17 bytes, 4956d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // emit a shuffle instruction. 4966d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher if (shiftVal <= 16) { 4976d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher const Type *IntTy = Type::getInt32Ty(C); 4986d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher const Type *EltTy = Type::getInt8Ty(C); 4996d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher const Type *VecTy = VectorType::get(EltTy, 16); 5006d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 5016d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Op2 = Builder.CreateBitCast(Op2, VecTy); 5026d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Op1 = Builder.CreateBitCast(Op1, VecTy); 5036d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 5046d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher llvm::SmallVector<llvm::Constant*, 16> Indices; 5056d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher for (unsigned i = 0; i != 16; ++i) 5066d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Indices.push_back(ConstantInt::get(IntTy, shiftVal + i)); 5076d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 5086d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Value *SV = ConstantVector::get(Indices.begin(), Indices.size()); 5096d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Rep = Builder.CreateShuffleVector(Op2, Op1, SV, "palignr"); 5106d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Rep = Builder.CreateBitCast(Rep, F->getReturnType()); 5116d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher } 5126d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 5136d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // If palignr is shifting the pair of input vectors more than 16 but less 5146d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // than 32 bytes, emit a logical right shift of the destination. 5156d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher else if (shiftVal < 32) { 5166d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher const Type *EltTy = Type::getInt64Ty(C); 5176d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher const Type *VecTy = VectorType::get(EltTy, 2); 5186d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher const Type *IntTy = Type::getInt32Ty(C); 5196d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 5206d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Op1 = Builder.CreateBitCast(Op1, VecTy, "cast"); 5216d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Op2 = ConstantInt::get(IntTy, (shiftVal-16) * 8); 5226d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 5236d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // create i32 constant 5246d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Function *I = 5256d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Intrinsic::getDeclaration(F->getParent(), Intrinsic::x86_sse2_psrl_dq); 5266d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Rep = Builder.CreateCall2(I, Op1, Op2, "palignr"); 5276d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher } 5286d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 5296d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // If palignr is shifting the pair of vectors more than 32 bytes, emit zero. 5306d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher else { 5316d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher Rep = Constant::getNullValue(F->getReturnType()); 5326d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher } 5336d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 5346d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // Replace any uses with our new instruction. 5356d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher if (!CI->use_empty()) 5366d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher CI->replaceAllUsesWith(Rep); 5376d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 5386d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher // Remove upgraded instruction. 5396d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher CI->eraseFromParent(); 5406d972fd087a29dcb063b86e3b81957d9e19ff8f1Eric Christopher 541a5cecd0a130f7ebc4787f8f5b3e8959e41786673Evan Cheng } else { 542c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable("Unknown function for CallInst upgrade."); 543f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng } 544f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng return; 545f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng } 546f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng 547051a950000e21935165db56695e35bade668193bGabor Greif switch (NewFn->getIntrinsicID()) { 548c23197a26f34f559ea9797de51e187087c039c42Torok Edwin default: llvm_unreachable("Unknown function for CallInst upgrade."); 549d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson case Intrinsic::x86_mmx_psll_d: 550d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson case Intrinsic::x86_mmx_psll_q: 551d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson case Intrinsic::x86_mmx_psll_w: 552d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson case Intrinsic::x86_mmx_psra_d: 553d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson case Intrinsic::x86_mmx_psra_w: 554d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson case Intrinsic::x86_mmx_psrl_d: 555d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson case Intrinsic::x86_mmx_psrl_q: 556d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson case Intrinsic::x86_mmx_psrl_w: { 55758d74910c6b82e622ecbb57d6644d48fec5a5c0fChris Lattner Value *Operands[2]; 558d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson 559f2937ac4eddb5ced78a1d73206de020c6d9e440fGabor Greif Operands[0] = CI->getArgOperand(0); 560d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson 561d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson // Cast the second parameter to the correct type. 562f2937ac4eddb5ced78a1d73206de020c6d9e440fGabor Greif BitCastInst *BC = new BitCastInst(CI->getArgOperand(1), 563d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson NewFn->getFunctionType()->getParamType(1), 5644797f61657fc32d2e4e806f9f8faadf3fee3e64cEvan Cheng "upgraded.", CI); 56558d74910c6b82e622ecbb57d6644d48fec5a5c0fChris Lattner Operands[1] = BC; 566d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson 567d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson // Construct a new CallInst 568051a950000e21935165db56695e35bade668193bGabor Greif CallInst *NewCI = CallInst::Create(NewFn, Operands, Operands+2, 569051a950000e21935165db56695e35bade668193bGabor Greif "upgraded."+CI->getName(), CI); 570d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson NewCI->setTailCall(CI->isTailCall()); 571d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson NewCI->setCallingConv(CI->getCallingConv()); 572d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson 573d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson // Handle any uses of the old CallInst. 574d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson if (!CI->use_empty()) 575d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson // Replace all uses of the old call with the new cast which has the 576d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson // correct type. 577d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson CI->replaceAllUsesWith(NewCI); 578d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson 579d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson // Clean up the old call now that it has been completely upgraded. 580d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson CI->eraseFromParent(); 581d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson break; 582d04764a8acabe0b3f0452b3099bc5964ba783884Anders Carlsson } 5836994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth case Intrinsic::ctlz: 5846994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth case Intrinsic::ctpop: 585051a950000e21935165db56695e35bade668193bGabor Greif case Intrinsic::cttz: { 586551754c4958086cc6910da7c950f2875e212f5cfEric Christopher // Build a small vector of the 1..(N-1) operands, which are the 5876994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // parameters. 588551754c4958086cc6910da7c950f2875e212f5cfEric Christopher SmallVector<Value*, 8> Operands(CI->op_begin()+1, CI->op_end()); 5896994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 5906994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // Construct a new CallInst 591051a950000e21935165db56695e35bade668193bGabor Greif CallInst *NewCI = CallInst::Create(NewFn, Operands.begin(), Operands.end(), 592051a950000e21935165db56695e35bade668193bGabor Greif "upgraded."+CI->getName(), CI); 5936994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth NewCI->setTailCall(CI->isTailCall()); 5946994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth NewCI->setCallingConv(CI->getCallingConv()); 5956994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 5966994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // Handle any uses of the old CallInst. 5976994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth if (!CI->use_empty()) { 5986994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // Check for sign extend parameter attributes on the return values. 5990598866c052147c31b808391f58434ce3dbfb838Devang Patel bool SrcSExt = NewFn->getAttributes().paramHasAttr(0, Attribute::SExt); 6000598866c052147c31b808391f58434ce3dbfb838Devang Patel bool DestSExt = F->getAttributes().paramHasAttr(0, Attribute::SExt); 6016994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 6026994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // Construct an appropriate cast from the new return type to the old. 6037cbd8a3e92221437048b484d5ef9c0a22d0f8c58Gabor Greif CastInst *RetCast = CastInst::Create( 6046994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth CastInst::getCastOpcode(NewCI, SrcSExt, 6056994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth F->getReturnType(), 6066994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth DestSExt), 6076994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth NewCI, F->getReturnType(), 6086994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth NewCI->getName(), CI); 6096994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth NewCI->moveBefore(RetCast); 6106994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 6116994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // Replace all uses of the old call with the new cast which has the 6126994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // correct type. 6136994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth CI->replaceAllUsesWith(RetCast); 6146994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth } 6156994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 6166994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // Clean up the old call now that it has been completely upgraded. 6176994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth CI->eraseFromParent(); 618051a950000e21935165db56695e35bade668193bGabor Greif } 619051a950000e21935165db56695e35bade668193bGabor Greif break; 620b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands case Intrinsic::eh_selector: 621b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands case Intrinsic::eh_typeid_for: { 622b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands // Only the return type changed. 623551754c4958086cc6910da7c950f2875e212f5cfEric Christopher SmallVector<Value*, 8> Operands(CI->op_begin() + 1, CI->op_end()); 624b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands CallInst *NewCI = CallInst::Create(NewFn, Operands.begin(), Operands.end(), 625b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands "upgraded." + CI->getName(), CI); 626b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands NewCI->setTailCall(CI->isTailCall()); 627b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands NewCI->setCallingConv(CI->getCallingConv()); 628b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands 629b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands // Handle any uses of the old CallInst. 630b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands if (!CI->use_empty()) { 631b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands // Construct an appropriate cast from the new return type to the old. 632b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands CastInst *RetCast = 633b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands CastInst::Create(CastInst::getCastOpcode(NewCI, true, 634b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands F->getReturnType(), true), 635b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands NewCI, F->getReturnType(), NewCI->getName(), CI); 636b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands CI->replaceAllUsesWith(RetCast); 637b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands } 638b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands CI->eraseFromParent(); 639b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands } 640b01bbdcc1af27bd90b552bb1b62b48916e0d4be3Duncan Sands break; 64120adc9dc4650313f017b27d9818eb2176238113dMon P Wang case Intrinsic::memcpy: 64220adc9dc4650313f017b27d9818eb2176238113dMon P Wang case Intrinsic::memmove: 64320adc9dc4650313f017b27d9818eb2176238113dMon P Wang case Intrinsic::memset: { 64420adc9dc4650313f017b27d9818eb2176238113dMon P Wang // Add isVolatile 64520adc9dc4650313f017b27d9818eb2176238113dMon P Wang const llvm::Type *I1Ty = llvm::Type::getInt1Ty(CI->getContext()); 646f2937ac4eddb5ced78a1d73206de020c6d9e440fGabor Greif Value *Operands[5] = { CI->getArgOperand(0), CI->getArgOperand(1), 647f2937ac4eddb5ced78a1d73206de020c6d9e440fGabor Greif CI->getArgOperand(2), CI->getArgOperand(3), 64820adc9dc4650313f017b27d9818eb2176238113dMon P Wang llvm::ConstantInt::get(I1Ty, 0) }; 64920adc9dc4650313f017b27d9818eb2176238113dMon P Wang CallInst *NewCI = CallInst::Create(NewFn, Operands, Operands+5, 65020adc9dc4650313f017b27d9818eb2176238113dMon P Wang CI->getName(), CI); 65120adc9dc4650313f017b27d9818eb2176238113dMon P Wang NewCI->setTailCall(CI->isTailCall()); 65220adc9dc4650313f017b27d9818eb2176238113dMon P Wang NewCI->setCallingConv(CI->getCallingConv()); 65320adc9dc4650313f017b27d9818eb2176238113dMon P Wang // Handle any uses of the old CallInst. 65420adc9dc4650313f017b27d9818eb2176238113dMon P Wang if (!CI->use_empty()) 65520adc9dc4650313f017b27d9818eb2176238113dMon P Wang // Replace all uses of the old call with the new cast which has the 65620adc9dc4650313f017b27d9818eb2176238113dMon P Wang // correct type. 65720adc9dc4650313f017b27d9818eb2176238113dMon P Wang CI->replaceAllUsesWith(NewCI); 65820adc9dc4650313f017b27d9818eb2176238113dMon P Wang 65920adc9dc4650313f017b27d9818eb2176238113dMon P Wang // Clean up the old call now that it has been completely upgraded. 66020adc9dc4650313f017b27d9818eb2176238113dMon P Wang CI->eraseFromParent(); 66120adc9dc4650313f017b27d9818eb2176238113dMon P Wang break; 66220adc9dc4650313f017b27d9818eb2176238113dMon P Wang } 6636994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth } 6646994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth} 6656994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 6666994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth// This tests each Function to determine if it needs upgrading. When we find 6676994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth// one we are interested in, we then upgrade all calls to reflect the new 6686994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth// function. 6696994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruthvoid llvm::UpgradeCallsToIntrinsic(Function* F) { 6706994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth assert(F && "Illegal attempt to upgrade a non-existent intrinsic."); 6716994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth 6726994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // Upgrade the function and check if it is a totaly new function. 673f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng Function* NewFn; 674f9b83fcf95e8a280d7b117af8858596fe5b10d94Evan Cheng if (UpgradeIntrinsicFunction(F, NewFn)) { 6756994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth if (NewFn != F) { 6766994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // Replace all uses to the old function with the new one if necessary. 6776994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth for (Value::use_iterator UI = F->use_begin(), UE = F->use_end(); 6786994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth UI != UE; ) { 6796994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth if (CallInst* CI = dyn_cast<CallInst>(*UI++)) 6806994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth UpgradeIntrinsicCall(CI, NewFn); 6816994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth } 6826994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth // Remove old function, no longer used, from the module. 6836994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth F->eraseFromParent(); 6846994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth } 6856994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth } 6866994040a952e5fb27605eb3cf29ed86c4e59cf62Chandler Carruth} 687e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel 688771150accba7ab3480746a451710ac81f950fac2Victor Hernandez/// This function strips all debug info intrinsics, except for llvm.dbg.declare. 689771150accba7ab3480746a451710ac81f950fac2Victor Hernandez/// If an llvm.dbg.declare intrinsic is invalid, then this function simply 690771150accba7ab3480746a451710ac81f950fac2Victor Hernandez/// strips that use. 691e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patelvoid llvm::CheckDebugInfoIntrinsics(Module *M) { 692e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel 693e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel 694e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel if (Function *FuncStart = M->getFunction("llvm.dbg.func.start")) { 69544a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel while (!FuncStart->use_empty()) { 69644a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel CallInst *CI = cast<CallInst>(FuncStart->use_back()); 69744a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel CI->eraseFromParent(); 698e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel } 69944a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel FuncStart->eraseFromParent(); 700e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel } 70144a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel 702e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel if (Function *StopPoint = M->getFunction("llvm.dbg.stoppoint")) { 70344a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel while (!StopPoint->use_empty()) { 70444a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel CallInst *CI = cast<CallInst>(StopPoint->use_back()); 70544a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel CI->eraseFromParent(); 706e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel } 70744a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel StopPoint->eraseFromParent(); 708e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel } 709e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel 710e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel if (Function *RegionStart = M->getFunction("llvm.dbg.region.start")) { 71144a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel while (!RegionStart->use_empty()) { 71244a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel CallInst *CI = cast<CallInst>(RegionStart->use_back()); 71344a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel CI->eraseFromParent(); 714e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel } 71544a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel RegionStart->eraseFromParent(); 716e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel } 717e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel 718e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel if (Function *RegionEnd = M->getFunction("llvm.dbg.region.end")) { 71944a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel while (!RegionEnd->use_empty()) { 72044a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel CallInst *CI = cast<CallInst>(RegionEnd->use_back()); 72144a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel CI->eraseFromParent(); 722e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel } 72344a29e066a24e88bdf127e88be4380a5f259c4b4Devang Patel RegionEnd->eraseFromParent(); 724e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel } 725e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel 726e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel if (Function *Declare = M->getFunction("llvm.dbg.declare")) { 727e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel if (!Declare->use_empty()) { 728e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel DbgDeclareInst *DDI = cast<DbgDeclareInst>(Declare->use_back()); 729f2937ac4eddb5ced78a1d73206de020c6d9e440fGabor Greif if (!isa<MDNode>(DDI->getArgOperand(0)) || 730f2937ac4eddb5ced78a1d73206de020c6d9e440fGabor Greif !isa<MDNode>(DDI->getArgOperand(1))) { 731e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel while (!Declare->use_empty()) { 732e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel CallInst *CI = cast<CallInst>(Declare->use_back()); 733e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel CI->eraseFromParent(); 734e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel } 735e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel Declare->eraseFromParent(); 736e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel } 737e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel } 738e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel } 739e4b275610a7a05b7ee4c0378a906a6330e4c4ab0Devang Patel} 740