@@ -2046,6 +2046,27 @@ static bool DetermineNoUndef(QualType QTy, CodeGenTypes &Types,
2046
2046
return false ;
2047
2047
}
2048
2048
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
+
2049
2070
// / Construct the IR attribute list of a function or call.
2050
2071
// /
2051
2072
// / When adding an attribute, please consider where it should be handled:
@@ -4821,6 +4842,9 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
4821
4842
unsigned FirstIRArg, NumIRArgs;
4822
4843
std::tie (FirstIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs (ArgNo);
4823
4844
4845
+ bool ArgHasMaybeUndefAttr =
4846
+ IsArgumentMaybeUndef (TargetDecl, CallInfo.getNumRequiredArgs (), ArgNo);
4847
+
4824
4848
switch (ArgInfo.getKind ()) {
4825
4849
case ABIArgInfo::InAlloca: {
4826
4850
assert (NumIRArgs == 0 );
@@ -4879,7 +4903,11 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
4879
4903
// Make a temporary alloca to pass the argument.
4880
4904
Address Addr = CreateMemTempWithoutCast (
4881
4905
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;
4883
4911
4884
4912
I->copyInto (*this , Addr);
4885
4913
} else {
@@ -4937,7 +4965,10 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
4937
4965
// Create an aligned temporary, and copy to it.
4938
4966
Address AI = CreateMemTempWithoutCast (
4939
4967
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;
4941
4972
4942
4973
// Emit lifetime markers for the temporary alloca.
4943
4974
llvm::TypeSize ByvalTempElementSize =
@@ -4956,9 +4987,13 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
4956
4987
auto *T = llvm::PointerType::getWithSamePointeeType (
4957
4988
cast<llvm::PointerType>(V->getType ()),
4958
4989
CGM.getDataLayout ().getAllocaAddrSpace ());
4959
- IRCallArgs[FirstIRArg] = getTargetHooks ().performAddrSpaceCast (
4990
+
4991
+ llvm::Value *Val = getTargetHooks ().performAddrSpaceCast (
4960
4992
*this , V, LangAS::Default, CGM.getASTAllocaAddressSpace (), T,
4961
4993
true );
4994
+ if (ArgHasMaybeUndefAttr)
4995
+ Val = Builder.CreateFreeze (Val);
4996
+ IRCallArgs[FirstIRArg] = Val;
4962
4997
}
4963
4998
}
4964
4999
break ;
@@ -5012,6 +5047,8 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
5012
5047
V->getType () != IRFuncTy->getParamType (FirstIRArg))
5013
5048
V = Builder.CreateBitCast (V, IRFuncTy->getParamType (FirstIRArg));
5014
5049
5050
+ if (ArgHasMaybeUndefAttr)
5051
+ V = Builder.CreateFreeze (V);
5015
5052
IRCallArgs[FirstIRArg] = V;
5016
5053
break ;
5017
5054
}
@@ -5056,6 +5093,8 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
5056
5093
for (unsigned i = 0 , e = STy->getNumElements (); i != e; ++i) {
5057
5094
Address EltPtr = Builder.CreateStructGEP (Src, i);
5058
5095
llvm::Value *LI = Builder.CreateLoad (EltPtr);
5096
+ if (ArgHasMaybeUndefAttr)
5097
+ LI = Builder.CreateFreeze (LI);
5059
5098
IRCallArgs[FirstIRArg + i] = LI;
5060
5099
}
5061
5100
} else {
@@ -5072,6 +5111,9 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
5072
5111
if (ATy != nullptr && isa<RecordType>(I->Ty .getCanonicalType ()))
5073
5112
Load = EmitCMSEClearRecord (Load, ATy, I->Ty );
5074
5113
}
5114
+
5115
+ if (ArgHasMaybeUndefAttr)
5116
+ Load = Builder.CreateFreeze (Load);
5075
5117
IRCallArgs[FirstIRArg] = Load;
5076
5118
}
5077
5119
@@ -5117,6 +5159,8 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
5117
5159
if (ABIArgInfo::isPaddingForCoerceAndExpand (eltType)) continue ;
5118
5160
Address eltAddr = Builder.CreateStructGEP (addr, i);
5119
5161
llvm::Value *elt = Builder.CreateLoad (eltAddr);
5162
+ if (ArgHasMaybeUndefAttr)
5163
+ elt = Builder.CreateFreeze (elt);
5120
5164
IRCallArgs[IRArgPos++] = elt;
5121
5165
}
5122
5166
assert (IRArgPos == FirstIRArg + NumIRArgs);
0 commit comments