@@ -2028,9 +2028,19 @@ struct DSEState {
2028
2028
if (!InnerCallee)
2029
2029
return false ;
2030
2030
LibFunc Func;
2031
+ std::optional<StringRef> ZeroedVariantName = std::nullopt;
2031
2032
if (!TLI.getLibFunc (*InnerCallee, Func) || !TLI.has (Func) ||
2032
- Func != LibFunc_malloc)
2033
- return false ;
2033
+ Func != LibFunc_malloc) {
2034
+ if (!Malloc->hasFnAttr (" alloc-variant-zeroed" ) ||
2035
+ Malloc->getFnAttr (" alloc-variant-zeroed" )
2036
+ .getValueAsString ()
2037
+ .empty ()) {
2038
+ return false ;
2039
+ }
2040
+ ZeroedVariantName =
2041
+ Malloc->getFnAttr (" alloc-variant-zeroed" ).getValueAsString ();
2042
+ }
2043
+
2034
2044
// Gracefully handle malloc with unexpected memory attributes.
2035
2045
auto *MallocDef = dyn_cast_or_null<MemoryDef>(MSSA.getMemoryAccess (Malloc));
2036
2046
if (!MallocDef)
@@ -2057,15 +2067,38 @@ struct DSEState {
2057
2067
2058
2068
if (Malloc->getOperand (0 ) != MemSet->getLength ())
2059
2069
return false ;
2060
- if (!shouldCreateCalloc (Malloc, MemSet) ||
2061
- !DT.dominates (Malloc, MemSet) ||
2070
+ if (!shouldCreateCalloc (Malloc, MemSet) || !DT.dominates (Malloc, MemSet) ||
2062
2071
!memoryIsNotModifiedBetween (Malloc, MemSet, BatchAA, DL, &DT))
2063
2072
return false ;
2064
2073
IRBuilder<> IRB (Malloc);
2065
- Type *SizeTTy = Malloc->getArgOperand (0 )->getType ();
2066
- auto *Calloc =
2067
- emitCalloc (ConstantInt::get (SizeTTy, 1 ), Malloc->getArgOperand (0 ), IRB,
2068
- TLI, Malloc->getType ()->getPointerAddressSpace ());
2074
+ assert (Func == LibFunc_malloc || ZeroedVariantName.has_value ());
2075
+ Value *Calloc = nullptr ;
2076
+ if (ZeroedVariantName.has_value ()) {
2077
+ auto *ZeroedVariant =
2078
+ Malloc->getModule ()->getFunction (*ZeroedVariantName);
2079
+ if (!ZeroedVariant)
2080
+ return false ;
2081
+ auto Attributes = ZeroedVariant->getAttributes ();
2082
+ auto MallocFamily = getAllocationFamily (Malloc, &TLI);
2083
+ if (MallocFamily &&
2084
+ *MallocFamily !=
2085
+ Attributes.getFnAttr (" alloc-family" ).getValueAsString ())
2086
+ return false ;
2087
+ if (!Attributes.hasFnAttr (Attribute::AllocKind) ||
2088
+ (Attributes.getAllocKind () & AllocFnKind::Zeroed) ==
2089
+ AllocFnKind::Unknown)
2090
+ return false ;
2091
+
2092
+ SmallVector<Value *, 3 > Args;
2093
+ for (unsigned I = 0 ; I < Malloc->arg_size (); I++)
2094
+ Args.push_back (Malloc->getArgOperand (I));
2095
+ Calloc = IRB.CreateCall (ZeroedVariant, Args, *ZeroedVariantName);
2096
+ } else {
2097
+ Type *SizeTTy = Malloc->getArgOperand (0 )->getType ();
2098
+ Calloc =
2099
+ emitCalloc (ConstantInt::get (SizeTTy, 1 ), Malloc->getArgOperand (0 ),
2100
+ IRB, TLI, Malloc->getType ()->getPointerAddressSpace ());
2101
+ }
2069
2102
if (!Calloc)
2070
2103
return false ;
2071
2104
0 commit comments