@@ -2046,6 +2046,27 @@ static bool DetermineNoUndef(QualType QTy, CodeGenTypes &Types,
20462046 return false ;
20472047}
20482048
2049+ // / Check if the argument of a function has maybe_undef attribute.
2050+ static bool IsArgumentMaybeUndef (const Decl *TargetDecl,
2051+ unsigned NumRequiredArgs, unsigned ArgNo) {
2052+ const auto *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl);
2053+ if (!FD)
2054+ return false ;
2055+
2056+ // Assume variadic arguments do not have maybe_undef attribute.
2057+ if (ArgNo >= NumRequiredArgs)
2058+ return false ;
2059+
2060+ // Check if argument has maybe_undef attribute.
2061+ if (ArgNo < FD->getNumParams ()) {
2062+ const ParmVarDecl *Param = FD->getParamDecl (ArgNo);
2063+ if (Param && Param->hasAttr <MaybeUndefAttr>())
2064+ return true ;
2065+ }
2066+
2067+ return false ;
2068+ }
2069+
20492070// / Construct the IR attribute list of a function or call.
20502071// /
20512072// / When adding an attribute, please consider where it should be handled:
@@ -4821,6 +4842,9 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
48214842 unsigned FirstIRArg, NumIRArgs;
48224843 std::tie (FirstIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs (ArgNo);
48234844
4845+ bool ArgHasMaybeUndefAttr =
4846+ IsArgumentMaybeUndef (TargetDecl, CallInfo.getNumRequiredArgs (), ArgNo);
4847+
48244848 switch (ArgInfo.getKind ()) {
48254849 case ABIArgInfo::InAlloca: {
48264850 assert (NumIRArgs == 0 );
@@ -4879,7 +4903,11 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
48794903 // Make a temporary alloca to pass the argument.
48804904 Address Addr = CreateMemTempWithoutCast (
48814905 I->Ty , ArgInfo.getIndirectAlign (), " indirect-arg-temp" );
4882- IRCallArgs[FirstIRArg] = Addr.getPointer ();
4906+
4907+ llvm::Value *Val = Addr.getPointer ();
4908+ if (ArgHasMaybeUndefAttr)
4909+ Val = Builder.CreateFreeze (Addr.getPointer ());
4910+ IRCallArgs[FirstIRArg] = Val;
48834911
48844912 I->copyInto (*this , Addr);
48854913 } else {
@@ -4937,7 +4965,10 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
49374965 // Create an aligned temporary, and copy to it.
49384966 Address AI = CreateMemTempWithoutCast (
49394967 I->Ty , ArgInfo.getIndirectAlign (), " byval-temp" );
4940- IRCallArgs[FirstIRArg] = AI.getPointer ();
4968+ llvm::Value *Val = AI.getPointer ();
4969+ if (ArgHasMaybeUndefAttr)
4970+ Val = Builder.CreateFreeze (AI.getPointer ());
4971+ IRCallArgs[FirstIRArg] = Val;
49414972
49424973 // Emit lifetime markers for the temporary alloca.
49434974 llvm::TypeSize ByvalTempElementSize =
@@ -4956,9 +4987,13 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
49564987 auto *T = llvm::PointerType::getWithSamePointeeType (
49574988 cast<llvm::PointerType>(V->getType ()),
49584989 CGM.getDataLayout ().getAllocaAddrSpace ());
4959- IRCallArgs[FirstIRArg] = getTargetHooks ().performAddrSpaceCast (
4990+
4991+ llvm::Value *Val = getTargetHooks ().performAddrSpaceCast (
49604992 *this , V, LangAS::Default, CGM.getASTAllocaAddressSpace (), T,
49614993 true );
4994+ if (ArgHasMaybeUndefAttr)
4995+ Val = Builder.CreateFreeze (Val);
4996+ IRCallArgs[FirstIRArg] = Val;
49624997 }
49634998 }
49644999 break ;
@@ -5012,6 +5047,8 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
50125047 V->getType () != IRFuncTy->getParamType (FirstIRArg))
50135048 V = Builder.CreateBitCast (V, IRFuncTy->getParamType (FirstIRArg));
50145049
5050+ if (ArgHasMaybeUndefAttr)
5051+ V = Builder.CreateFreeze (V);
50155052 IRCallArgs[FirstIRArg] = V;
50165053 break ;
50175054 }
@@ -5056,6 +5093,8 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
50565093 for (unsigned i = 0 , e = STy->getNumElements (); i != e; ++i) {
50575094 Address EltPtr = Builder.CreateStructGEP (Src, i);
50585095 llvm::Value *LI = Builder.CreateLoad (EltPtr);
5096+ if (ArgHasMaybeUndefAttr)
5097+ LI = Builder.CreateFreeze (LI);
50595098 IRCallArgs[FirstIRArg + i] = LI;
50605099 }
50615100 } else {
@@ -5072,6 +5111,9 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
50725111 if (ATy != nullptr && isa<RecordType>(I->Ty .getCanonicalType ()))
50735112 Load = EmitCMSEClearRecord (Load, ATy, I->Ty );
50745113 }
5114+
5115+ if (ArgHasMaybeUndefAttr)
5116+ Load = Builder.CreateFreeze (Load);
50755117 IRCallArgs[FirstIRArg] = Load;
50765118 }
50775119
@@ -5117,6 +5159,8 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
51175159 if (ABIArgInfo::isPaddingForCoerceAndExpand (eltType)) continue ;
51185160 Address eltAddr = Builder.CreateStructGEP (addr, i);
51195161 llvm::Value *elt = Builder.CreateLoad (eltAddr);
5162+ if (ArgHasMaybeUndefAttr)
5163+ elt = Builder.CreateFreeze (elt);
51205164 IRCallArgs[IRArgPos++] = elt;
51215165 }
51225166 assert (IRArgPos == FirstIRArg + NumIRArgs);
0 commit comments