Skip to content

Commit 71f7b97

Browse files
authored
[Local] Make combineAAMetadata() more principled (#122091)
This moves combineAAMetadata() into Local and implements it via a new AAOnly flag, which will intersect only AA metadata and keep other known metadata. The existing KnownIDs list is dropped, because it is redundant with the switch in combineMetadata(), which already drops unknown metadata. I tried a few variants of this, and ultimately went with the AAOnly flag because this way we make an explicit choice for each metadata kind supported by combineMetadata(), and ignoring the flag gives you conservatively correct behavior. I checked that the memcpy tests still pass if we adjust the logic for MD_memprof/MD_callsite to drop the metadata instead of arbitrarily picking one. Fixes #121495.
1 parent 1b29435 commit 71f7b97

File tree

3 files changed

+32
-71
lines changed

3 files changed

+32
-71
lines changed

llvm/include/llvm/Transforms/Utils/Local.h

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -412,19 +412,6 @@ Instruction *removeUnwindEdge(BasicBlock *BB, DomTreeUpdater *DTU = nullptr);
412412
bool removeUnreachableBlocks(Function &F, DomTreeUpdater *DTU = nullptr,
413413
MemorySSAUpdater *MSSAU = nullptr);
414414

415-
/// DO NOT CALL EXTERNALLY.
416-
/// FIXME: https://github.com/llvm/llvm-project/issues/121495
417-
/// Once external callers of this function are removed, either inline into
418-
/// combineMetadataForCSE, or internalize and remove KnownIDs parameter.
419-
///
420-
/// Combine the metadata of two instructions so that K can replace J. Some
421-
/// metadata kinds can only be kept if K does not move, meaning it dominated
422-
/// J in the original IR.
423-
///
424-
/// Metadata not listed as known via KnownIDs is removed
425-
void combineMetadata(Instruction *K, const Instruction *J,
426-
ArrayRef<unsigned> KnownIDs, bool DoesKMove);
427-
428415
/// Combine the metadata of two instructions so that K can replace J. This
429416
/// specifically handles the case of CSE-like transformations. Some
430417
/// metadata can only be kept if K dominates J. For this to be correct,
@@ -434,6 +421,11 @@ void combineMetadata(Instruction *K, const Instruction *J,
434421
void combineMetadataForCSE(Instruction *K, const Instruction *J,
435422
bool DoesKMove);
436423

424+
/// Combine metadata of two instructions, where instruction J is a memory
425+
/// access that has been merged into K. This will intersect alias-analysis
426+
/// metadata, while preserving other known metadata.
427+
void combineAAMetadata(Instruction *K, const Instruction *J);
428+
437429
/// Copy the metadata from the source instruction to the destination (the
438430
/// replacement for the source instruction).
439431
void copyMetadataForLoad(LoadInst &Dest, const LoadInst &Source);

llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -341,21 +341,6 @@ static bool writtenBetween(MemorySSA *MSSA, BatchAAResults &AA,
341341
return !MSSA->dominates(Clobber, Start);
342342
}
343343

344-
// Update AA metadata
345-
static void combineAAMetadata(Instruction *ReplInst, Instruction *I) {
346-
// FIXME: MD_tbaa_struct and MD_mem_parallel_loop_access should also be
347-
// handled here, but combineMetadata doesn't support them yet
348-
unsigned KnownIDs[] = {
349-
LLVMContext::MD_tbaa, LLVMContext::MD_alias_scope,
350-
LLVMContext::MD_noalias, LLVMContext::MD_invariant_group,
351-
LLVMContext::MD_access_group, LLVMContext::MD_prof,
352-
LLVMContext::MD_memprof, LLVMContext::MD_callsite};
353-
// FIXME: https://github.com/llvm/llvm-project/issues/121495
354-
// Use custom AA metadata combining handling instead of combineMetadata, which
355-
// is meant for CSE and will drop any metadata not in the KnownIDs list.
356-
combineMetadata(ReplInst, I, KnownIDs, true);
357-
}
358-
359344
/// When scanning forward over instructions, we look for some other patterns to
360345
/// fold away. In particular, this looks for stores to neighboring locations of
361346
/// memory. If it sees enough consecutive ones, it attempts to merge them

llvm/lib/Transforms/Utils/Local.cpp

Lines changed: 27 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -3308,31 +3308,27 @@ bool llvm::removeUnreachableBlocks(Function &F, DomTreeUpdater *DTU,
33083308
return Changed;
33093309
}
33103310

3311-
// FIXME: https://github.com/llvm/llvm-project/issues/121495
3312-
// Once external callers of this function are removed, either inline into
3313-
// combineMetadataForCSE, or internalize and remove KnownIDs parameter.
3314-
void llvm::combineMetadata(Instruction *K, const Instruction *J,
3315-
ArrayRef<unsigned> KnownIDs, bool DoesKMove) {
3311+
/// If AAOnly is set, only intersect alias analysis metadata and preserve other
3312+
/// known metadata. Unknown metadata is always dropped.
3313+
static void combineMetadata(Instruction *K, const Instruction *J,
3314+
bool DoesKMove, bool AAOnly = false) {
33163315
SmallVector<std::pair<unsigned, MDNode *>, 4> Metadata;
3317-
K->dropUnknownNonDebugMetadata(KnownIDs);
33183316
K->getAllMetadataOtherThanDebugLoc(Metadata);
33193317
for (const auto &MD : Metadata) {
33203318
unsigned Kind = MD.first;
33213319
MDNode *JMD = J->getMetadata(Kind);
33223320
MDNode *KMD = MD.second;
33233321

3322+
// TODO: Assert that this switch is exhaustive for fixed MD kinds.
33243323
switch (Kind) {
33253324
default:
3326-
// FIXME: https://github.com/llvm/llvm-project/issues/121495
3327-
// Change to removing only explicitly listed other metadata, and assert
3328-
// on unknown metadata, to avoid inadvertently dropping newly added
3329-
// metadata types.
33303325
K->setMetadata(Kind, nullptr); // Remove unknown metadata
33313326
break;
33323327
case LLVMContext::MD_dbg:
33333328
llvm_unreachable("getAllMetadataOtherThanDebugLoc returned a MD_dbg");
33343329
case LLVMContext::MD_DIAssignID:
3335-
K->mergeDIAssignID(J);
3330+
if (!AAOnly)
3331+
K->mergeDIAssignID(J);
33363332
break;
33373333
case LLVMContext::MD_tbaa:
33383334
if (DoesKMove)
@@ -3353,11 +3349,12 @@ void llvm::combineMetadata(Instruction *K, const Instruction *J,
33533349
intersectAccessGroups(K, J));
33543350
break;
33553351
case LLVMContext::MD_range:
3356-
if (DoesKMove || !K->hasMetadata(LLVMContext::MD_noundef))
3352+
if (!AAOnly && (DoesKMove || !K->hasMetadata(LLVMContext::MD_noundef)))
33573353
K->setMetadata(Kind, MDNode::getMostGenericRange(JMD, KMD));
33583354
break;
33593355
case LLVMContext::MD_fpmath:
3360-
K->setMetadata(Kind, MDNode::getMostGenericFPMath(JMD, KMD));
3356+
if (!AAOnly)
3357+
K->setMetadata(Kind, MDNode::getMostGenericFPMath(JMD, KMD));
33613358
break;
33623359
case LLVMContext::MD_invariant_load:
33633360
// If K moves, only set the !invariant.load if it is present in both
@@ -3366,7 +3363,7 @@ void llvm::combineMetadata(Instruction *K, const Instruction *J,
33663363
K->setMetadata(Kind, JMD);
33673364
break;
33683365
case LLVMContext::MD_nonnull:
3369-
if (DoesKMove || !K->hasMetadata(LLVMContext::MD_noundef))
3366+
if (!AAOnly && (DoesKMove || !K->hasMetadata(LLVMContext::MD_noundef)))
33703367
K->setMetadata(Kind, JMD);
33713368
break;
33723369
case LLVMContext::MD_invariant_group:
@@ -3376,36 +3373,39 @@ void llvm::combineMetadata(Instruction *K, const Instruction *J,
33763373
// Combine MMRAs
33773374
break;
33783375
case LLVMContext::MD_align:
3379-
if (DoesKMove || !K->hasMetadata(LLVMContext::MD_noundef))
3376+
if (!AAOnly && (DoesKMove || !K->hasMetadata(LLVMContext::MD_noundef)))
33803377
K->setMetadata(
33813378
Kind, MDNode::getMostGenericAlignmentOrDereferenceable(JMD, KMD));
33823379
break;
33833380
case LLVMContext::MD_dereferenceable:
33843381
case LLVMContext::MD_dereferenceable_or_null:
3385-
if (DoesKMove)
3382+
if (!AAOnly && DoesKMove)
33863383
K->setMetadata(Kind,
33873384
MDNode::getMostGenericAlignmentOrDereferenceable(JMD, KMD));
33883385
break;
33893386
case LLVMContext::MD_memprof:
3390-
K->setMetadata(Kind, MDNode::getMergedMemProfMetadata(KMD, JMD));
3387+
if (!AAOnly)
3388+
K->setMetadata(Kind, MDNode::getMergedMemProfMetadata(KMD, JMD));
33913389
break;
33923390
case LLVMContext::MD_callsite:
3393-
K->setMetadata(Kind, MDNode::getMergedCallsiteMetadata(KMD, JMD));
3391+
if (!AAOnly)
3392+
K->setMetadata(Kind, MDNode::getMergedCallsiteMetadata(KMD, JMD));
33943393
break;
33953394
case LLVMContext::MD_preserve_access_index:
33963395
// Preserve !preserve.access.index in K.
33973396
break;
33983397
case LLVMContext::MD_noundef:
33993398
// If K does move, keep noundef if it is present in both instructions.
3400-
if (DoesKMove)
3399+
if (!AAOnly && DoesKMove)
34013400
K->setMetadata(Kind, JMD);
34023401
break;
34033402
case LLVMContext::MD_nontemporal:
34043403
// Preserve !nontemporal if it is present on both instructions.
3405-
K->setMetadata(Kind, JMD);
3404+
if (!AAOnly)
3405+
K->setMetadata(Kind, JMD);
34063406
break;
34073407
case LLVMContext::MD_prof:
3408-
if (DoesKMove)
3408+
if (!AAOnly && DoesKMove)
34093409
K->setMetadata(Kind, MDNode::getMergedProfMetadata(KMD, JMD, K, J));
34103410
break;
34113411
case LLVMContext::MD_noalias_addrspace:
@@ -3437,28 +3437,12 @@ void llvm::combineMetadata(Instruction *K, const Instruction *J,
34373437
}
34383438

34393439
void llvm::combineMetadataForCSE(Instruction *K, const Instruction *J,
3440-
bool KDominatesJ) {
3441-
unsigned KnownIDs[] = {LLVMContext::MD_tbaa,
3442-
LLVMContext::MD_alias_scope,
3443-
LLVMContext::MD_noalias,
3444-
LLVMContext::MD_range,
3445-
LLVMContext::MD_fpmath,
3446-
LLVMContext::MD_invariant_load,
3447-
LLVMContext::MD_nonnull,
3448-
LLVMContext::MD_invariant_group,
3449-
LLVMContext::MD_align,
3450-
LLVMContext::MD_dereferenceable,
3451-
LLVMContext::MD_dereferenceable_or_null,
3452-
LLVMContext::MD_access_group,
3453-
LLVMContext::MD_preserve_access_index,
3454-
LLVMContext::MD_prof,
3455-
LLVMContext::MD_nontemporal,
3456-
LLVMContext::MD_noundef,
3457-
LLVMContext::MD_mmra,
3458-
LLVMContext::MD_noalias_addrspace,
3459-
LLVMContext::MD_memprof,
3460-
LLVMContext::MD_callsite};
3461-
combineMetadata(K, J, KnownIDs, KDominatesJ);
3440+
bool DoesKMove) {
3441+
combineMetadata(K, J, DoesKMove);
3442+
}
3443+
3444+
void llvm::combineAAMetadata(Instruction *K, const Instruction *J) {
3445+
combineMetadata(K, J, /*DoesKMove=*/true, /*AAOnly=*/true);
34623446
}
34633447

34643448
void llvm::copyMetadataForLoad(LoadInst &Dest, const LoadInst &Source) {

0 commit comments

Comments
 (0)