-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[SelectionDAG] Mark frame index as "aliased" at argument copy elison #89712
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
Conversation
@llvm/pr-subscribers-llvm-selectiondag Author: Björn Pettersson (bjope) ChangesThis is a fix for miscompiles reported in After argument copy elison the IR value for the eliminated alloca Full diff: https://github.com/llvm/llvm-project/pull/89712.diff 3 Files Affected:
diff --git a/llvm/include/llvm/CodeGen/MachineFrameInfo.h b/llvm/include/llvm/CodeGen/MachineFrameInfo.h
index 0fe73fec7ee67f..a2c78e9e093d01 100644
--- a/llvm/include/llvm/CodeGen/MachineFrameInfo.h
+++ b/llvm/include/llvm/CodeGen/MachineFrameInfo.h
@@ -701,6 +701,13 @@ class MachineFrameInfo {
return Objects[ObjectIdx+NumFixedObjects].isAliased;
}
+ /// Set "maybe pointed to by an LLVM IR value" for an object.
+ void setIsAliasedObjectIndex(int ObjectIdx, bool IsAliased) {
+ assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
+ "Invalid Object Idx!");
+ Objects[ObjectIdx+NumFixedObjects].isAliased = IsAliased;
+ }
+
/// Returns true if the specified index corresponds to an immutable object.
bool isImmutableObjectIndex(int ObjectIdx) const {
// Tail calling functions can clobber their function arguments.
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 3f69f7ad54477e..319465865fb1d1 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -11128,7 +11128,7 @@ static void tryToElideArgumentCopy(
}
// Perform the elision. Delete the old stack object and replace its only use
- // in the variable info map. Mark the stack object as mutable.
+ // in the variable info map. Mark the stack object as mutable and aliased.
LLVM_DEBUG({
dbgs() << "Eliding argument copy from " << Arg << " to " << *AI << '\n'
<< " Replacing frame index " << OldIndex << " with " << FixedIndex
@@ -11136,6 +11136,7 @@ static void tryToElideArgumentCopy(
});
MFI.RemoveStackObject(OldIndex);
MFI.setIsImmutableObjectIndex(FixedIndex, false);
+ MFI.setIsAliasedObjectIndex(FixedIndex, true);
AllocaIndex = FixedIndex;
ArgCopyElisionFrameIndexMap.insert({OldIndex, FixedIndex});
for (SDValue ArgVal : ArgVals)
diff --git a/llvm/test/CodeGen/Hexagon/arg-copy-elison.ll b/llvm/test/CodeGen/Hexagon/arg-copy-elison.ll
new file mode 100644
index 00000000000000..f7902e65c46953
--- /dev/null
+++ b/llvm/test/CodeGen/Hexagon/arg-copy-elison.ll
@@ -0,0 +1,39 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
+; RUN: llc -mtriple hexagon-- -O3 -o - %s | FileCheck %s
+
+; Reproducer for https://github.com/llvm/llvm-project/issues/89060
+;
+; Problem was a bug in argument copy elison. Given that the %alloca is
+; eliminated, the same frame index will be used for accessing %alloca and %a
+; on the fixed stack. Care must be taken when setting up
+; MachinePointerInfo/MemOperands for those accesses to either make sure that
+; we always refer to the fixed stack slot the same way (not using the
+; ir.alloca name), or make sure that we still detect that they alias each
+; other if using different kinds of MemOperands to identify the same fixed
+; stack entry.
+;
+define i32 @f(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 %q1, i32 %a, i32 %q2) {
+; CHECK-LABEL: f:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: // %bb.0:
+; CHECK-NEXT: {
+; CHECK-NEXT: r0 = memw(r29+#36)
+; CHECK-NEXT: r1 = memw(r29+#28)
+; CHECK-NEXT: }
+; CHECK-NEXT: {
+; CHECK-NEXT: r0 = sub(r1,r0)
+; CHECK-NEXT: r2 = memw(r29+#32)
+; CHECK-NEXT: memw(r29+#32) = ##666
+; CHECK-NEXT: }
+; CHECK-NEXT: {
+; CHECK-NEXT: r0 = xor(r0,r2)
+; CHECK-NEXT: jumpr r31
+; CHECK-NEXT: }
+ %alloca = alloca i32
+ store i32 %a, ptr %alloca ; Should be elided.
+ store i32 666, ptr %alloca
+ %x = sub i32 %q1, %q2
+ %y = xor i32 %x, %a ; Results in a load of %a from fixed stack.
+ ; Using same frame index as elided %alloca.
+ ret i32 %y
+}
|
You can test this locally with the following command:git-clang-format --diff 56ed3dd77f4ef07a9b35cbb3d0ca868cc0999d01 5d7f7b4c33ef69af1348d1265882359d6cc1d853 -- llvm/include/llvm/CodeGen/MachineFrameInfo.h llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp View the diff from clang-format here.diff --git a/llvm/include/llvm/CodeGen/MachineFrameInfo.h b/llvm/include/llvm/CodeGen/MachineFrameInfo.h
index a2c78e9e09..8c60c0d091 100644
--- a/llvm/include/llvm/CodeGen/MachineFrameInfo.h
+++ b/llvm/include/llvm/CodeGen/MachineFrameInfo.h
@@ -703,9 +703,9 @@ public:
/// Set "maybe pointed to by an LLVM IR value" for an object.
void setIsAliasedObjectIndex(int ObjectIdx, bool IsAliased) {
- assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
+ assert(unsigned(ObjectIdx + NumFixedObjects) < Objects.size() &&
"Invalid Object Idx!");
- Objects[ObjectIdx+NumFixedObjects].isAliased = IsAliased;
+ Objects[ObjectIdx + NumFixedObjects].isAliased = IsAliased;
}
/// Returns true if the specified index corresponds to an immutable object.
|
@@ -0,0 +1,39 @@ | |||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 | |||
; RUN: llc -mtriple hexagon-- -O3 -o - %s | FileCheck %s |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you really need the -O3? It doesn't make a difference on most targets and -O2 is the default
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like -O2 also reproduce the failure (while -O1 won't trigger the problem). I'll change it to -O2.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just drop the flag
@@ -11128,14 +11128,15 @@ static void tryToElideArgumentCopy( | |||
} | |||
|
|||
// Perform the elision. Delete the old stack object and replace its only use | |||
// in the variable info map. Mark the stack object as mutable. | |||
// in the variable info map. Mark the stack object as mutable and aliased. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any practical difference between the mutable and isAliased cases? Where is the ultimate alias query that goes wrong?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isAliased is used inside ScheduleDAGInstrs.cpp getUnderlyingObjectsForInstr:
if (const PseudoSourceValue *PSV = MMO->getPseudoValue()) {
// Function that contain tail calls don't have unique PseudoSourceValue
// objects. Two PseudoSourceValues might refer to the same or
// overlapping locations. The client code calling this function assumes
// this is not the case. So return a conservative answer of no known
// object.
if (MFI.hasTailCall())
return false;
// For now, ignore PseudoSourceValues which may alias LLVM IR values
// because the code that uses this function has no way to cope with
// such aliases.
if (PSV->isAliased(&MFI))
return false;
bool MayAlias = PSV->mayAlias(&MFI);
Objects.emplace_back(PSV, MayAlias);
} else if (const Value *V = MMO->getValue()) {
@@ -701,6 +701,13 @@ class MachineFrameInfo { | |||
return Objects[ObjectIdx+NumFixedObjects].isAliased; | |||
} | |||
|
|||
/// Set "maybe pointed to by an LLVM IR value" for an object. | |||
void setIsAliasedObjectIndex(int ObjectIdx, bool IsAliased) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
void setIsAliasedObjectIndex(int ObjectIdx, bool IsAliased) { | |
void setIsAliasedObjectIndex(int ObjectIdx, bool IsAliased = true) { |
LLVM_DEBUG({ | ||
dbgs() << "Eliding argument copy from " << Arg << " to " << *AI << '\n' | ||
<< " Replacing frame index " << OldIndex << " with " << FixedIndex | ||
<< '\n'; | ||
}); | ||
MFI.RemoveStackObject(OldIndex); | ||
MFI.setIsImmutableObjectIndex(FixedIndex, false); | ||
MFI.setIsAliasedObjectIndex(FixedIndex, true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MFI.setIsAliasedObjectIndex(FixedIndex, true); | |
MFI.setIsAliasedObjectIndex(FixedIndex); |
@@ -0,0 +1,39 @@ | |||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 | |||
; RUN: llc -mtriple hexagon-- -O3 -o - %s | FileCheck %s |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just drop the flag
This is a fix for miscompiles reported in llvm#89060 After argument copy elison the IR value for the eliminated alloca is aliasing with the fixed stack object. This patch is making sure that we mark the fixed stack object as being aliased with IR values to avoid that for example schedulers are reordering accesses to the fixed stack object. This could otherwise happen when there is a mix of MemOperands refering the shared fixed stack slow via both the IR value for the elided alloca, and via a fixed stack pseudo source value (as would be the case when lowering the arguments).
/cherry-pick d8b253b |
Error: Command failed due to missing milestone. |
…lvm#89712) This is a fix for miscompiles reported in llvm#89060 After argument copy elison the IR value for the eliminated alloca is aliasing with the fixed stack object. This patch is making sure that we mark the fixed stack object as being aliased with IR values to avoid that for example schedulers are reordering accesses to the fixed stack object. This could otherwise happen when there is a mix of MemOperands refering the shared fixed stack slow via both the IR value for the elided alloca, and via a fixed stack pseudo source value (as would be the case when lowering the arguments). (cherry picked from commit d8b253b)
…lvm#89712) This is a fix for miscompiles reported in llvm#89060 After argument copy elison the IR value for the eliminated alloca is aliasing with the fixed stack object. This patch is making sure that we mark the fixed stack object as being aliased with IR values to avoid that for example schedulers are reordering accesses to the fixed stack object. This could otherwise happen when there is a mix of MemOperands refering the shared fixed stack slow via both the IR value for the elided alloca, and via a fixed stack pseudo source value (as would be the case when lowering the arguments). (cherry picked from commit d8b253b)
This is a fix for miscompiles reported in
#89060
After argument copy elison the IR value for the eliminated alloca
is aliasing with the fixed stack object. This patch is making sure
that we mark the fixed stack object as being aliased with IR values
to avoid that for example schedulers are reordering accesses to
the fixed stack object. This could otherwise happen when there is a
mix of MemOperands refering the shared fixed stack slow via both
the IR value for the elided alloca, and via a fixed stack pseudo
source value (as would be the case when lowering the arguments).