@@ -2555,24 +2555,20 @@ static bool HaveNonOverlappingStorage(const Value *V1, const Value *V2) {
25552555 //
25562556 // So, we'll assume that two non-empty allocas have different addresses
25572557 // for now.
2558-
2559- auto isByValArgOrGlobalVarOrAlloca = [](const Value *V) {
2560- if (const Argument *A = dyn_cast<Argument>(V))
2561- return A->hasByValAttr ();
2562- return isa<AllocaInst>(V) || isa<GlobalVariable>(V);
2558+ auto isByValArg = [](const Value *V) {
2559+ const Argument *A = dyn_cast<Argument>(V);
2560+ return A && A->hasByValAttr ();
25632561 };
25642562
2565- if (!isByValArgOrGlobalVarOrAlloca (V1) ||
2566- !isByValArgOrGlobalVarOrAlloca (V2))
2567- return false ;
2563+ // Byval args are backed by store which does not overlap with each other,
2564+ // allocas, or globals.
2565+ if (isByValArg (V1))
2566+ return isa<AllocaInst>(V2) || isa<GlobalVariable>(V2) || isByValArg (V2);
2567+ if (isByValArg (V2))
2568+ return isa<AllocaInst>(V1) || isa<GlobalVariable>(V1) || isByValArg (V1);
25682569
2569- // Both sides being globals shouldn't reach here - as the resulting compare
2570- // is a constantexpr - but we want to guard against it to be safe. The
2571- // semantics of globals are complicated by e.g. unnamed_addr. The assumption
2572- // in this code is that while two globals could end up overlapping, they'll
2573- // never overlap with any alloca or byval, and thus we can still reason about
2574- // *one* global and one *non* global as disjoint storage.
2575- return !isa<GlobalVariable>(V1) || !isa<GlobalVariable>(V2);
2570+ return isa<AllocaInst>(V1) &&
2571+ (isa<AllocaInst>(V2) || isa<GlobalVariable>(V2));
25762572}
25772573
25782574// A significant optimization not implemented here is assuming that alloca
0 commit comments