diff options
Diffstat (limited to 'llvm/lib/IR/AutoUpgrade.cpp')
| -rw-r--r-- | llvm/lib/IR/AutoUpgrade.cpp | 376 |
1 files changed, 320 insertions, 56 deletions
diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp index 75594f90c926..7b9c55ff30a5 100644 --- a/llvm/lib/IR/AutoUpgrade.cpp +++ b/llvm/lib/IR/AutoUpgrade.cpp @@ -82,6 +82,26 @@ static bool UpgradeX86MaskedFPCompare(Function *F, Intrinsic::ID IID, return true; } +static bool UpgradeX86BF16Intrinsic(Function *F, Intrinsic::ID IID, + Function *&NewFn) { + if (F->getReturnType()->getScalarType()->isBFloatTy()) + return false; + + rename(F); + NewFn = Intrinsic::getDeclaration(F->getParent(), IID); + return true; +} + +static bool UpgradeX86BF16DPIntrinsic(Function *F, Intrinsic::ID IID, + Function *&NewFn) { + if (F->getFunctionType()->getParamType(1)->getScalarType()->isBFloatTy()) + return false; + + rename(F); + NewFn = Intrinsic::getDeclaration(F->getParent(), IID); + return true; +} + static bool ShouldUpgradeX86Intrinsic(Function *F, StringRef Name) { // All of the intrinsics matches below should be marked with which llvm // version started autoupgrading them. At some point in the future we would @@ -488,6 +508,33 @@ static bool UpgradeX86IntrinsicFunction(Function *F, StringRef Name, if (Name == "avx512.mask.cmp.ps.512") // Added in 7.0 return UpgradeX86MaskedFPCompare(F, Intrinsic::x86_avx512_mask_cmp_ps_512, NewFn); + if (Name == "avx512bf16.cvtne2ps2bf16.128") // Added in 9.0 + return UpgradeX86BF16Intrinsic( + F, Intrinsic::x86_avx512bf16_cvtne2ps2bf16_128, NewFn); + if (Name == "avx512bf16.cvtne2ps2bf16.256") // Added in 9.0 + return UpgradeX86BF16Intrinsic( + F, Intrinsic::x86_avx512bf16_cvtne2ps2bf16_256, NewFn); + if (Name == "avx512bf16.cvtne2ps2bf16.512") // Added in 9.0 + return UpgradeX86BF16Intrinsic( + F, Intrinsic::x86_avx512bf16_cvtne2ps2bf16_512, NewFn); + if (Name == "avx512bf16.mask.cvtneps2bf16.128") // Added in 9.0 + return UpgradeX86BF16Intrinsic( + F, Intrinsic::x86_avx512bf16_mask_cvtneps2bf16_128, NewFn); + if (Name == "avx512bf16.cvtneps2bf16.256") // Added in 9.0 + return UpgradeX86BF16Intrinsic( + F, Intrinsic::x86_avx512bf16_cvtneps2bf16_256, NewFn); + if (Name == "avx512bf16.cvtneps2bf16.512") // Added in 9.0 + return UpgradeX86BF16Intrinsic( + F, Intrinsic::x86_avx512bf16_cvtneps2bf16_512, NewFn); + if (Name == "avx512bf16.dpbf16ps.128") // Added in 9.0 + return UpgradeX86BF16DPIntrinsic( + F, Intrinsic::x86_avx512bf16_dpbf16ps_128, NewFn); + if (Name == "avx512bf16.dpbf16ps.256") // Added in 9.0 + return UpgradeX86BF16DPIntrinsic( + F, Intrinsic::x86_avx512bf16_dpbf16ps_256, NewFn); + if (Name == "avx512bf16.dpbf16ps.512") // Added in 9.0 + return UpgradeX86BF16DPIntrinsic( + F, Intrinsic::x86_avx512bf16_dpbf16ps_512, NewFn); // frcz.ss/sd may need to have an argument dropped. Added in 3.2 if (Name.startswith("xop.vfrcz.ss") && F->arg_size() == 2) { @@ -536,7 +583,7 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) { // Quickly eliminate it, if it's not a candidate. StringRef Name = F->getName(); - if (Name.size() <= 8 || !Name.startswith("llvm.")) + if (Name.size() <= 7 || !Name.startswith("llvm.")) return false; Name = Name.substr(5); // Strip off "llvm." @@ -558,6 +605,59 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) { F->arg_begin()->getType()); return true; } + if (Name == "aarch64.sve.bfdot.lane") { + NewFn = Intrinsic::getDeclaration(F->getParent(), + Intrinsic::aarch64_sve_bfdot_lane_v2); + return true; + } + if (Name == "aarch64.sve.bfmlalb.lane") { + NewFn = Intrinsic::getDeclaration(F->getParent(), + Intrinsic::aarch64_sve_bfmlalb_lane_v2); + return true; + } + if (Name == "aarch64.sve.bfmlalt.lane") { + NewFn = Intrinsic::getDeclaration(F->getParent(), + Intrinsic::aarch64_sve_bfmlalt_lane_v2); + return true; + } + static const Regex LdRegex("^aarch64\\.sve\\.ld[234](.nxv[a-z0-9]+|$)"); + if (LdRegex.match(Name)) { + Type *ScalarTy = + dyn_cast<VectorType>(F->getReturnType())->getElementType(); + ElementCount EC = + dyn_cast<VectorType>(F->arg_begin()->getType())->getElementCount(); + Type *Ty = VectorType::get(ScalarTy, EC); + Intrinsic::ID ID = + StringSwitch<Intrinsic::ID>(Name) + .StartsWith("aarch64.sve.ld2", Intrinsic::aarch64_sve_ld2_sret) + .StartsWith("aarch64.sve.ld3", Intrinsic::aarch64_sve_ld3_sret) + .StartsWith("aarch64.sve.ld4", Intrinsic::aarch64_sve_ld4_sret) + .Default(Intrinsic::not_intrinsic); + NewFn = Intrinsic::getDeclaration(F->getParent(), ID, Ty); + return true; + } + if (Name.startswith("aarch64.sve.tuple.get")) { + Type *Tys[] = {F->getReturnType(), F->arg_begin()->getType()}; + NewFn = Intrinsic::getDeclaration(F->getParent(), + Intrinsic::vector_extract, Tys); + return true; + } + if (Name.startswith("aarch64.sve.tuple.set")) { + auto Args = F->getFunctionType()->params(); + Type *Tys[] = {Args[0], Args[2], Args[1]}; + NewFn = Intrinsic::getDeclaration(F->getParent(), + Intrinsic::vector_insert, Tys); + return true; + } + static const Regex CreateTupleRegex( + "^aarch64\\.sve\\.tuple\\.create[234](.nxv[a-z0-9]+|$)"); + if (CreateTupleRegex.match(Name)) { + auto Args = F->getFunctionType()->params(); + Type *Tys[] = {F->getReturnType(), Args[1]}; + NewFn = Intrinsic::getDeclaration(F->getParent(), + Intrinsic::vector_insert, Tys); + return true; + } if (Name.startswith("arm.neon.vclz")) { Type* args[2] = { F->arg_begin()->getType(), @@ -808,6 +908,13 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) { } break; } + case 'f': + if (Name.startswith("flt.rounds")) { + rename(F); + NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::get_rounding); + return true; + } + break; case 'i': case 'l': { bool IsLifetimeStart = Name.startswith("lifetime.start"); @@ -993,9 +1100,9 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) { } } else if (Name.startswith("ptr.annotation.") && F->arg_size() == 4) { rename(F); - NewFn = Intrinsic::getDeclaration(F->getParent(), - Intrinsic::ptr_annotation, - F->arg_begin()->getType()); + NewFn = Intrinsic::getDeclaration( + F->getParent(), Intrinsic::ptr_annotation, + {F->arg_begin()->getType(), F->getArg(1)->getType()}); return true; } break; @@ -1010,8 +1117,9 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) { case 'v': { if (Name == "var.annotation" && F->arg_size() == 4) { rename(F); - NewFn = Intrinsic::getDeclaration(F->getParent(), - Intrinsic::var_annotation); + NewFn = Intrinsic::getDeclaration( + F->getParent(), Intrinsic::var_annotation, + {{F->arg_begin()->getType(), F->getArg(1)->getType()}}); return true; } break; @@ -1040,7 +1148,7 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) { Name, F->getParent()); // The new function may also need remangling. - if (auto Result = llvm::Intrinsic::remangleIntrinsicFunction(F)) + if (auto Result = llvm::Intrinsic::remangleIntrinsicFunction(NewFn)) NewFn = *Result; return true; } @@ -1048,7 +1156,7 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) { // Remangle our intrinsic since we upgrade the mangling auto Result = llvm::Intrinsic::remangleIntrinsicFunction(F); - if (Result != None) { + if (Result != std::nullopt) { NewFn = *Result; return true; } @@ -1131,7 +1239,7 @@ static Value *UpgradeX86PSLLDQIntrinsics(IRBuilder<> &Builder, Idxs[l + i] = Idx + l; } - Res = Builder.CreateShuffleVector(Res, Op, makeArrayRef(Idxs, NumElts)); + Res = Builder.CreateShuffleVector(Res, Op, ArrayRef(Idxs, NumElts)); } // Bitcast back to a 64-bit element type. @@ -1165,7 +1273,7 @@ static Value *UpgradeX86PSRLDQIntrinsics(IRBuilder<> &Builder, Value *Op, Idxs[l + i] = Idx + l; } - Res = Builder.CreateShuffleVector(Op, Res, makeArrayRef(Idxs, NumElts)); + Res = Builder.CreateShuffleVector(Op, Res, ArrayRef(Idxs, NumElts)); } // Bitcast back to a 64-bit element type. @@ -1185,8 +1293,8 @@ static Value *getX86MaskVec(IRBuilder<> &Builder, Value *Mask, int Indices[4]; for (unsigned i = 0; i != NumElts; ++i) Indices[i] = i; - Mask = Builder.CreateShuffleVector( - Mask, Mask, makeArrayRef(Indices, NumElts), "extract"); + Mask = Builder.CreateShuffleVector(Mask, Mask, ArrayRef(Indices, NumElts), + "extract"); } return Mask; @@ -1260,9 +1368,8 @@ static Value *UpgradeX86ALIGNIntrinsics(IRBuilder<> &Builder, Value *Op0, } } - Value *Align = Builder.CreateShuffleVector(Op1, Op0, - makeArrayRef(Indices, NumElts), - "palignr"); + Value *Align = Builder.CreateShuffleVector( + Op1, Op0, ArrayRef(Indices, NumElts), "palignr"); return EmitX86Select(Builder, Mask, Align, Passthru); } @@ -1452,7 +1559,7 @@ static Value *UpgradeMaskedStore(IRBuilder<> &Builder, llvm::PointerType::getUnqual(Data->getType())); const Align Alignment = Aligned - ? Align(Data->getType()->getPrimitiveSizeInBits().getFixedSize() / 8) + ? Align(Data->getType()->getPrimitiveSizeInBits().getFixedValue() / 8) : Align(1); // If the mask is all ones just emit a regular store. @@ -1474,8 +1581,9 @@ static Value *UpgradeMaskedLoad(IRBuilder<> &Builder, Ptr = Builder.CreateBitCast(Ptr, llvm::PointerType::getUnqual(ValTy)); const Align Alignment = Aligned - ? Align(Passthru->getType()->getPrimitiveSizeInBits().getFixedSize() / - 8) + ? Align( + Passthru->getType()->getPrimitiveSizeInBits().getFixedValue() / + 8) : Align(1); // If the mask is all ones just emit a regular store. @@ -1957,13 +2065,17 @@ static Value *UpgradeARMIntrinsicCall(StringRef Name, CallBase *CI, Function *F, /// Upgrade a call to an old intrinsic. All argument and return casting must be /// provided to seamlessly integrate with existing context. void llvm::UpgradeIntrinsicCall(CallBase *CI, Function *NewFn) { - Function *F = CI->getCalledFunction(); + // Note dyn_cast to Function is not quite the same as getCalledFunction, which + // checks the callee's function type matches. It's likely we need to handle + // type changes here. + Function *F = dyn_cast<Function>(CI->getCalledOperand()); + if (!F) + return; + LLVMContext &C = CI->getContext(); IRBuilder<> Builder(C); Builder.SetInsertPoint(CI->getParent(), CI->getIterator()); - assert(F && "Intrinsic call is not direct?"); - if (!NewFn) { // Get the Function's name. StringRef Name = F->getName(); @@ -2024,7 +2136,7 @@ void llvm::UpgradeIntrinsicCall(CallBase *CI, Function *NewFn) { "cast"); StoreInst *SI = Builder.CreateAlignedStore( Arg1, BC, - Align(Arg1->getType()->getPrimitiveSizeInBits().getFixedSize() / 8)); + Align(Arg1->getType()->getPrimitiveSizeInBits().getFixedValue() / 8)); SI->setMetadata(M->getMDKindID("nontemporal"), Node); // Remove intrinsic. @@ -2164,14 +2276,13 @@ void llvm::UpgradeIntrinsicCall(CallBase *CI, Function *NewFn) { // First extract half of each vector. This gives better codegen than // doing it in a single shuffle. - LHS = Builder.CreateShuffleVector(LHS, LHS, - makeArrayRef(Indices, NumElts / 2)); - RHS = Builder.CreateShuffleVector(RHS, RHS, - makeArrayRef(Indices, NumElts / 2)); + LHS = + Builder.CreateShuffleVector(LHS, LHS, ArrayRef(Indices, NumElts / 2)); + RHS = + Builder.CreateShuffleVector(RHS, RHS, ArrayRef(Indices, NumElts / 2)); // Concat the vectors. // NOTE: Operands have to be swapped to match intrinsic definition. - Rep = Builder.CreateShuffleVector(RHS, LHS, - makeArrayRef(Indices, NumElts)); + Rep = Builder.CreateShuffleVector(RHS, LHS, ArrayRef(Indices, NumElts)); Rep = Builder.CreateBitCast(Rep, CI->getType()); } else if (IsX86 && Name == "avx512.kand.w") { Value *LHS = getX86MaskVec(Builder, CI->getArgOperand(0), 16); @@ -3365,7 +3476,7 @@ void llvm::UpgradeIntrinsicCall(CallBase *CI, Function *NewFn) { Ptr, PointerType::getUnqual(CI->getType()), "cast"); LoadInst *LI = Builder.CreateAlignedLoad( CI->getType(), BC, - Align(CI->getType()->getPrimitiveSizeInBits().getFixedSize() / 8)); + Align(CI->getType()->getPrimitiveSizeInBits().getFixedValue() / 8)); LI->setMetadata(M->getMDKindID("nontemporal"), Node); Rep = LI; } else if (IsX86 && (Name.startswith("fma.vfmadd.") || @@ -3824,21 +3935,29 @@ void llvm::UpgradeIntrinsicCall(CallBase *CI, Function *NewFn) { } // This must be an upgrade from a named to a literal struct. - auto *OldST = cast<StructType>(CI->getType()); - assert(OldST != NewFn->getReturnType() && "Return type must have changed"); - assert(OldST->getNumElements() == - cast<StructType>(NewFn->getReturnType())->getNumElements() && - "Must have same number of elements"); + if (auto *OldST = dyn_cast<StructType>(CI->getType())) { + assert(OldST != NewFn->getReturnType() && + "Return type must have changed"); + assert(OldST->getNumElements() == + cast<StructType>(NewFn->getReturnType())->getNumElements() && + "Must have same number of elements"); - SmallVector<Value *> Args(CI->args()); - Value *NewCI = Builder.CreateCall(NewFn, Args); - Value *Res = PoisonValue::get(OldST); - for (unsigned Idx = 0; Idx < OldST->getNumElements(); ++Idx) { - Value *Elem = Builder.CreateExtractValue(NewCI, Idx); - Res = Builder.CreateInsertValue(Res, Elem, Idx); + SmallVector<Value *> Args(CI->args()); + Value *NewCI = Builder.CreateCall(NewFn, Args); + Value *Res = PoisonValue::get(OldST); + for (unsigned Idx = 0; Idx < OldST->getNumElements(); ++Idx) { + Value *Elem = Builder.CreateExtractValue(NewCI, Idx); + Res = Builder.CreateInsertValue(Res, Elem, Idx); + } + CI->replaceAllUsesWith(Res); + CI->eraseFromParent(); + return; } - CI->replaceAllUsesWith(Res); - CI->eraseFromParent(); + + // We're probably about to produce something invalid. Let the verifier catch + // it instead of dying here. + CI->setCalledOperand( + ConstantExpr::getPointerCast(NewFn, CI->getCalledOperand()->getType())); return; }; CallInst *NewCall = nullptr; @@ -3858,6 +3977,94 @@ void llvm::UpgradeIntrinsicCall(CallBase *CI, Function *NewFn) { NewCall = Builder.CreateCall(NewFn, Args); break; } + case Intrinsic::aarch64_sve_bfmlalb_lane_v2: + case Intrinsic::aarch64_sve_bfmlalt_lane_v2: + case Intrinsic::aarch64_sve_bfdot_lane_v2: { + LLVMContext &Ctx = F->getParent()->getContext(); + SmallVector<Value *, 4> Args(CI->args()); + Args[3] = ConstantInt::get(Type::getInt32Ty(Ctx), + cast<ConstantInt>(Args[3])->getZExtValue()); + NewCall = Builder.CreateCall(NewFn, Args); + break; + } + case Intrinsic::aarch64_sve_ld3_sret: + case Intrinsic::aarch64_sve_ld4_sret: + case Intrinsic::aarch64_sve_ld2_sret: { + StringRef Name = F->getName(); + Name = Name.substr(5); + unsigned N = StringSwitch<unsigned>(Name) + .StartsWith("aarch64.sve.ld2", 2) + .StartsWith("aarch64.sve.ld3", 3) + .StartsWith("aarch64.sve.ld4", 4) + .Default(0); + ScalableVectorType *RetTy = + dyn_cast<ScalableVectorType>(F->getReturnType()); + unsigned MinElts = RetTy->getMinNumElements() / N; + SmallVector<Value *, 2> Args(CI->args()); + Value *NewLdCall = Builder.CreateCall(NewFn, Args); + Value *Ret = llvm::PoisonValue::get(RetTy); + for (unsigned I = 0; I < N; I++) { + Value *Idx = ConstantInt::get(Type::getInt64Ty(C), I * MinElts); + Value *SRet = Builder.CreateExtractValue(NewLdCall, I); + Ret = Builder.CreateInsertVector(RetTy, Ret, SRet, Idx); + } + NewCall = dyn_cast<CallInst>(Ret); + break; + } + + case Intrinsic::vector_extract: { + StringRef Name = F->getName(); + Name = Name.substr(5); // Strip llvm + if (!Name.startswith("aarch64.sve.tuple.get")) { + DefaultCase(); + return; + } + ScalableVectorType *RetTy = + dyn_cast<ScalableVectorType>(F->getReturnType()); + unsigned MinElts = RetTy->getMinNumElements(); + unsigned I = cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue(); + Value *NewIdx = ConstantInt::get(Type::getInt64Ty(C), I * MinElts); + NewCall = Builder.CreateCall(NewFn, {CI->getArgOperand(0), NewIdx}); + break; + } + + case Intrinsic::vector_insert: { + StringRef Name = F->getName(); + Name = Name.substr(5); + if (!Name.startswith("aarch64.sve.tuple")) { + DefaultCase(); + return; + } + if (Name.startswith("aarch64.sve.tuple.set")) { + unsigned I = dyn_cast<ConstantInt>(CI->getArgOperand(1))->getZExtValue(); + ScalableVectorType *Ty = + dyn_cast<ScalableVectorType>(CI->getArgOperand(2)->getType()); + Value *NewIdx = + ConstantInt::get(Type::getInt64Ty(C), I * Ty->getMinNumElements()); + NewCall = Builder.CreateCall( + NewFn, {CI->getArgOperand(0), CI->getArgOperand(2), NewIdx}); + break; + } + if (Name.startswith("aarch64.sve.tuple.create")) { + unsigned N = StringSwitch<unsigned>(Name) + .StartsWith("aarch64.sve.tuple.create2", 2) + .StartsWith("aarch64.sve.tuple.create3", 3) + .StartsWith("aarch64.sve.tuple.create4", 4) + .Default(0); + assert(N > 1 && "Create is expected to be between 2-4"); + ScalableVectorType *RetTy = + dyn_cast<ScalableVectorType>(F->getReturnType()); + Value *Ret = llvm::PoisonValue::get(RetTy); + unsigned MinElts = RetTy->getMinNumElements() / N; + for (unsigned I = 0; I < N; I++) { + Value *Idx = ConstantInt::get(Type::getInt64Ty(C), I * MinElts); + Value *V = CI->getArgOperand(I); + Ret = Builder.CreateInsertVector(RetTy, Ret, V, Idx); + } + NewCall = dyn_cast<CallInst>(Ret); + } + break; + } case Intrinsic::arm_neon_bfdot: case Intrinsic::arm_neon_bfmmla: @@ -3946,13 +4153,17 @@ void llvm::UpgradeIntrinsicCall(CallBase *CI, Function *NewFn) { case Intrinsic::var_annotation: // Upgrade from versions that lacked the annotation attribute argument. - assert(CI->arg_size() == 4 && - "Before LLVM 12.0 this intrinsic took four arguments"); + if (CI->arg_size() != 4) { + DefaultCase(); + return; + } // Create a new call with an added null annotation attribute argument. NewCall = Builder.CreateCall( NewFn, {CI->getArgOperand(0), CI->getArgOperand(1), CI->getArgOperand(2), CI->getArgOperand(3), Constant::getNullValue(Builder.getInt8PtrTy())}); + NewCall->takeName(CI); + CI->replaceAllUsesWith(NewCall); CI->eraseFromParent(); return; @@ -4054,6 +4265,43 @@ void llvm::UpgradeIntrinsicCall(CallBase *CI, Function *NewFn) { return; } + case Intrinsic::x86_avx512bf16_cvtne2ps2bf16_128: + case Intrinsic::x86_avx512bf16_cvtne2ps2bf16_256: + case Intrinsic::x86_avx512bf16_cvtne2ps2bf16_512: + case Intrinsic::x86_avx512bf16_mask_cvtneps2bf16_128: + case Intrinsic::x86_avx512bf16_cvtneps2bf16_256: + case Intrinsic::x86_avx512bf16_cvtneps2bf16_512: { + SmallVector<Value *, 4> Args(CI->args()); + unsigned NumElts = cast<FixedVectorType>(CI->getType())->getNumElements(); + if (NewFn->getIntrinsicID() == + Intrinsic::x86_avx512bf16_mask_cvtneps2bf16_128) + Args[1] = Builder.CreateBitCast( + Args[1], FixedVectorType::get(Builder.getBFloatTy(), NumElts)); + + NewCall = Builder.CreateCall(NewFn, Args); + Value *Res = Builder.CreateBitCast( + NewCall, FixedVectorType::get(Builder.getInt16Ty(), NumElts)); + + NewCall->takeName(CI); + CI->replaceAllUsesWith(Res); + CI->eraseFromParent(); + return; + } + case Intrinsic::x86_avx512bf16_dpbf16ps_128: + case Intrinsic::x86_avx512bf16_dpbf16ps_256: + case Intrinsic::x86_avx512bf16_dpbf16ps_512:{ + SmallVector<Value *, 4> Args(CI->args()); + unsigned NumElts = + cast<FixedVectorType>(CI->getType())->getNumElements() * 2; + Args[1] = Builder.CreateBitCast( + Args[1], FixedVectorType::get(Builder.getBFloatTy(), NumElts)); + Args[2] = Builder.CreateBitCast( + Args[2], FixedVectorType::get(Builder.getBFloatTy(), NumElts)); + + NewCall = Builder.CreateCall(NewFn, Args); + break; + } + case Intrinsic::thread_pointer: { NewCall = Builder.CreateCall(NewFn, {}); break; @@ -4391,26 +4639,34 @@ bool llvm::UpgradeModuleFlags(Module &M) { MDString *ID = dyn_cast_or_null<MDString>(Op->getOperand(1)); if (!ID) continue; + auto SetBehavior = [&](Module::ModFlagBehavior B) { + Metadata *Ops[3] = {ConstantAsMetadata::get(ConstantInt::get( + Type::getInt32Ty(M.getContext()), B)), + MDString::get(M.getContext(), ID->getString()), + Op->getOperand(2)}; + ModFlags->setOperand(I, MDNode::get(M.getContext(), Ops)); + Changed = true; + }; + if (ID->getString() == "Objective-C Image Info Version") HasObjCFlag = true; if (ID->getString() == "Objective-C Class Properties") HasClassProperties = true; - // Upgrade PIC/PIE Module Flags. The module flag behavior for these two - // field was Error and now they are Max. - if (ID->getString() == "PIC Level" || ID->getString() == "PIE Level") { + // Upgrade PIC from Error/Max to Min. + if (ID->getString() == "PIC Level") { if (auto *Behavior = mdconst::dyn_extract_or_null<ConstantInt>(Op->getOperand(0))) { - if (Behavior->getLimitedValue() == Module::Error) { - Type *Int32Ty = Type::getInt32Ty(M.getContext()); - Metadata *Ops[3] = { - ConstantAsMetadata::get(ConstantInt::get(Int32Ty, Module::Max)), - MDString::get(M.getContext(), ID->getString()), - Op->getOperand(2)}; - ModFlags->setOperand(I, MDNode::get(M.getContext(), Ops)); - Changed = true; - } + uint64_t V = Behavior->getLimitedValue(); + if (V == Module::Error || V == Module::Max) + SetBehavior(Module::Min); } } + // Upgrade "PIE Level" from Error to Max. + if (ID->getString() == "PIE Level") + if (auto *Behavior = + mdconst::dyn_extract_or_null<ConstantInt>(Op->getOperand(0))) + if (Behavior->getLimitedValue() == Module::Error) + SetBehavior(Module::Max); // Upgrade branch protection and return address signing module flags. The // module flag behavior for these fields were Error and now they are Min. @@ -4639,6 +4895,14 @@ std::string llvm::UpgradeDataLayoutString(StringRef DL, StringRef TT) { return DL.empty() ? std::string("G1") : (DL + "-G1").str(); } + if (T.isRISCV64()) { + // Make i32 a native type for 64-bit RISC-V. + auto I = DL.find("-n64-"); + if (I != StringRef::npos) + return (DL.take_front(I) + "-n32:64-" + DL.drop_front(I + 5)).str(); + return DL.str(); + } + std::string Res = DL.str(); if (!T.isX86()) return Res; |
