@@ -2028,9 +2028,18 @@ struct DSEState {
20282028 if (!InnerCallee)
20292029 return false ;
20302030 LibFunc Func;
2031+ std::optional<StringRef> ZeroedVariantName = std::nullopt ;
20312032 if (!TLI.getLibFunc (*InnerCallee, Func) || !TLI.has (Func) ||
2032- Func != LibFunc_malloc)
2033- return false ;
2033+ Func != LibFunc_malloc) {
2034+ if (!Malloc->getFnAttr (" alloc-variant-zeroed" ).isValid ()) {
2035+ return false ;
2036+ }
2037+ ZeroedVariantName =
2038+ Malloc->getFnAttr (" alloc-variant-zeroed" ).getValueAsString ();
2039+ if (ZeroedVariantName->empty ())
2040+ return false ;
2041+ }
2042+
20342043 // Gracefully handle malloc with unexpected memory attributes.
20352044 auto *MallocDef = dyn_cast_or_null<MemoryDef>(MSSA.getMemoryAccess (Malloc));
20362045 if (!MallocDef)
@@ -2057,15 +2066,31 @@ struct DSEState {
20572066
20582067 if (Malloc->getOperand (0 ) != MemSet->getLength ())
20592068 return false ;
2060- if (!shouldCreateCalloc (Malloc, MemSet) ||
2061- !DT.dominates (Malloc, MemSet) ||
2069+ if (!shouldCreateCalloc (Malloc, MemSet) || !DT.dominates (Malloc, MemSet) ||
20622070 !memoryIsNotModifiedBetween (Malloc, MemSet, BatchAA, DL, &DT))
20632071 return false ;
20642072 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 ());
2073+ assert (Func == LibFunc_malloc || ZeroedVariantName.has_value ());
2074+ Value *Calloc = nullptr ;
2075+ if (ZeroedVariantName.has_value ()) {
2076+ auto &Ctx = Malloc->getContext ();
2077+ auto Attr = InnerCallee->getAttributes ();
2078+ auto AllocKind = Attr.getFnAttr (Attribute::AllocKind).getAllocKind () |
2079+ AllocFnKind::Zeroed;
2080+ Attr =
2081+ Attr.addFnAttribute (Ctx, Attribute::getWithAllocKind (Ctx, AllocKind));
2082+ auto ZeroedVariant = Malloc->getModule ()->getOrInsertFunction (
2083+ *ZeroedVariantName, InnerCallee->getFunctionType (), Attr);
2084+ SmallVector<Value *, 3 > Args;
2085+ for (unsigned I = 0 ; I < Malloc->arg_size (); I++)
2086+ Args.push_back (Malloc->getArgOperand (I));
2087+ Calloc = IRB.CreateCall (ZeroedVariant, Args, *ZeroedVariantName);
2088+ } else {
2089+ Type *SizeTTy = Malloc->getArgOperand (0 )->getType ();
2090+ Calloc =
2091+ emitCalloc (ConstantInt::get (SizeTTy, 1 ), Malloc->getArgOperand (0 ),
2092+ IRB, TLI, Malloc->getType ()->getPointerAddressSpace ());
2093+ }
20692094 if (!Calloc)
20702095 return false ;
20712096
0 commit comments