Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[AST] Fix size merging for MustAlias sets #73820

Merged
merged 1 commit into from
Dec 7, 2023
Merged

[AST] Fix size merging for MustAlias sets #73820

merged 1 commit into from
Dec 7, 2023

Conversation

nikic
Copy link
Contributor

@nikic nikic commented Nov 29, 2023

AST checks aliasing with MustAlias sets by only checking the representative pointer (getSomePointer). This is only correct if the Size and AATags information of that pointer also includes the Size/AATags of all other pointers in the set.

When we add a new pointer to the AliasSet, we do perform this update (see the code in AliasSet::addPointer). However, if a pointer already in the MustAlias set is used with a new size, we currently do not update the representative pointer, resulting in miscompilations. Fix this by adding the missing update.

This is targeted fix using the current representation. There are a couple of alternatives:

  • For MustAlias sets, don't store per-pointer Size/AATags at all. This would make it clear that there is only one set of common Size/AATags for all pointers.
  • Check against all pointers in the set even for MustAlias. This is what [AST] Don't merge memory locations in AliasSetTracker #65731 proposes to do as part of a larger change to AST representation.

Fixes #64897.

AST checks aliasing with MustAlias sets by only checking the
representative pointer (getSomePointer). This is only correct
if the Size and AATags information of that pointer also includes
the Size/AATags of all other pointers in the set.

When we add a new pointer to the AliasSet, we do perform this
update (see the code in AliasSet::addPointer). However, if a
pointer already in the MustAlias set is used with a new size,
we currently do not update the representative pointer, resulting
in miscompilations. Fix this by adding the missing update.

This is targeted fix using the current representation. There are
a couple of alternatives:
 * For MustAlias sets, don't store per-pointer Size/AATags at all.
   This would make it clear that there is only one set of common
   Size/AATags for all pointers.
 * Check against all pointers in the set even for MustAlias. This
   is what llvm#65731
   proposes to do as part of a larger change to AST representation.

Fixes llvm#64897.
@llvmbot
Copy link
Collaborator

llvmbot commented Nov 29, 2023

@llvm/pr-subscribers-llvm-analysis

@llvm/pr-subscribers-llvm-transforms

Author: Nikita Popov (nikic)

Changes

AST checks aliasing with MustAlias sets by only checking the representative pointer (getSomePointer). This is only correct if the Size and AATags information of that pointer also includes the Size/AATags of all other pointers in the set.

When we add a new pointer to the AliasSet, we do perform this update (see the code in AliasSet::addPointer). However, if a pointer already in the MustAlias set is used with a new size, we currently do not update the representative pointer, resulting in miscompilations. Fix this by adding the missing update.

This is targeted fix using the current representation. There are a couple of alternatives:

  • For MustAlias sets, don't store per-pointer Size/AATags at all. This would make it clear that there is only one set of common Size/AATags for all pointers.
  • Check against all pointers in the set even for MustAlias. This is what [AST] Don't merge memory locations in AliasSetTracker #65731 proposes to do as part of a larger change to AST representation.

Fixes #64897.


Full diff: https://github.com/llvm/llvm-project/pull/73820.diff

2 Files Affected:

  • (modified) llvm/lib/Analysis/AliasSetTracker.cpp (+9-1)
  • (modified) llvm/test/Transforms/LICM/pr64897.ll (+3-5)
diff --git a/llvm/lib/Analysis/AliasSetTracker.cpp b/llvm/lib/Analysis/AliasSetTracker.cpp
index 91b889116dfa2d3..debdd328ce53fdc 100644
--- a/llvm/lib/Analysis/AliasSetTracker.cpp
+++ b/llvm/lib/Analysis/AliasSetTracker.cpp
@@ -348,8 +348,16 @@ AliasSet &AliasSetTracker::getAliasSetFor(const MemoryLocation &MemLoc) {
     // due to a quirk of alias analysis behavior. Since alias(undef, undef)
     // is NoAlias, mergeAliasSetsForPointer(undef, ...) will not find the
     // the right set for undef, even if it exists.
-    if (Entry.updateSizeAndAAInfo(Size, AAInfo))
+    if (Entry.updateSizeAndAAInfo(Size, AAInfo)) {
       mergeAliasSetsForPointer(Pointer, Size, AAInfo, MustAliasAll);
+
+      // For MustAlias sets, also update Size/AAInfo of the representative
+      // pointer.
+      AliasSet &AS = *Entry.getAliasSet(*this);
+      if (AS.isMustAlias())
+        if (AliasSet::PointerRec *P = AS.getSomePointer())
+          P->updateSizeAndAAInfo(Size, AAInfo);
+    }
     // Return the set!
     return *Entry.getAliasSet(*this)->getForwardedTarget(*this);
   }
diff --git a/llvm/test/Transforms/LICM/pr64897.ll b/llvm/test/Transforms/LICM/pr64897.ll
index 1ce78f15d797359..12b11eb6912b0cb 100644
--- a/llvm/test/Transforms/LICM/pr64897.ll
+++ b/llvm/test/Transforms/LICM/pr64897.ll
@@ -1,7 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
 ; RUN: opt -S -passes=licm < %s | FileCheck %s
 
-; FIXME: This is a miscompile.
 define void @test(i1 %c, i8 %x) {
 ; CHECK-LABEL: define void @test(
 ; CHECK-SAME: i1 [[C:%.*]], i8 [[X:%.*]]) {
@@ -10,17 +9,16 @@ define void @test(i1 %c, i8 %x) {
 ; CHECK-NEXT:    [[P:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 8
 ; CHECK-NEXT:    [[P_COPY:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 8
 ; CHECK-NEXT:    [[P2:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 12
-; CHECK-NEXT:    [[P2_PROMOTED:%.*]] = load i8, ptr [[P2]], align 1
 ; CHECK-NEXT:    br label [[LOOP:%.*]]
 ; CHECK:       loop:
-; CHECK-NEXT:    [[TMP0:%.*]] = phi i8 [ 0, [[LOOP]] ], [ [[P2_PROMOTED]], [[START:%.*]] ]
 ; CHECK-NEXT:    store i32 286331153, ptr [[P]], align 4
 ; CHECK-NEXT:    store i32 34, ptr [[P_COPY]], align 4
 ; CHECK-NEXT:    store i64 3689348814741910323, ptr [[P_COPY]], align 4
-; CHECK-NEXT:    call void @use(i8 [[TMP0]])
+; CHECK-NEXT:    [[VAL:%.*]] = load i8, ptr [[P2]], align 1
+; CHECK-NEXT:    call void @use(i8 [[VAL]])
+; CHECK-NEXT:    store i8 0, ptr [[P2]], align 1
 ; CHECK-NEXT:    br i1 [[C]], label [[LOOP]], label [[EXIT:%.*]]
 ; CHECK:       exit:
-; CHECK-NEXT:    store i8 0, ptr [[P2]], align 1
 ; CHECK-NEXT:    ret void
 ;
 start:

@jdoerfert
Copy link
Member

I'm in favor of #65731 if it solves this issue as well.

@nikic
Copy link
Contributor Author

nikic commented Dec 4, 2023

I'm in favor of #65731 if it solves this issue as well.

I'd still like a non-intrusive fix for this that is suitable for backport in the meantime.

Copy link
Member

@jdoerfert jdoerfert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LG, I hope this is going away with the other patch.

@nikic nikic merged commit 753c51b into llvm:main Dec 7, 2023
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

LICM miscompilation
3 participants