Skip to content

[CodeGenPrepare] Replace deleted ext instr with the promoted value. #71058

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

Merged
merged 6 commits into from
Jan 30, 2025

Conversation

dtcxzyw
Copy link
Member

@dtcxzyw dtcxzyw commented Nov 2, 2023

This PR replaces the deleted ext with the promoted value in AddrMode.
Fixes #70938.

@llvmbot
Copy link
Member

llvmbot commented Nov 2, 2023

@llvm/pr-subscribers-backend-x86

Author: Yingwei Zheng (dtcxzyw)

Changes

This PR replaces the deleted sext with the promoted value in AddrMode.
Fixes #70938.


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

2 Files Affected:

  • (modified) llvm/lib/CodeGen/CodeGenPrepare.cpp (+12)
  • (modified) llvm/test/CodeGen/X86/codegen-prepare-addrmode-sext.ll (+22)
diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp
index 187820717b6fd5c..9018b87835b775f 100644
--- a/llvm/lib/CodeGen/CodeGenPrepare.cpp
+++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp
@@ -2634,6 +2634,15 @@ struct ExtAddrMode : public TargetLowering::AddrMode {
   void print(raw_ostream &OS) const;
   void dump() const;
 
+  void replaceWith(Value *From, Value *To) {
+    if (BaseReg == From)
+      BaseReg = To;
+    if (ScaledReg == From)
+      ScaledReg = To;
+    if (OriginalValue == From)
+      OriginalValue = To;
+  }
+
   FieldName compare(const ExtAddrMode &other) {
     // First check that the types are the same on each field, as differing types
     // is something we can't cope with later on.
@@ -4933,6 +4942,9 @@ bool AddressingModeMatcher::matchOperationAddr(User *AddrInst, unsigned Opcode,
       TPT.rollback(LastKnownGood);
       return false;
     }
+
+    // SExt has been deleted. Make sure it is not referenced by the AddrMode.
+    AddrMode.replaceWith(Ext, PromotedOperand);
     return true;
   }
   }
diff --git a/llvm/test/CodeGen/X86/codegen-prepare-addrmode-sext.ll b/llvm/test/CodeGen/X86/codegen-prepare-addrmode-sext.ll
index 6e95c91e7398932..a7f6f803d58fd4c 100644
--- a/llvm/test/CodeGen/X86/codegen-prepare-addrmode-sext.ll
+++ b/llvm/test/CodeGen/X86/codegen-prepare-addrmode-sext.ll
@@ -507,3 +507,25 @@ define i8 @oneArgPromotionBlockSExtZExt(i1 %arg1, ptr %base) {
   %res = load i8, ptr %arrayidx
   ret i8 %res
 }
+
+; Check that we replace the deleted sext with the promoted value.
+; CHECK-LABEL: define void @pr70938(
+; CHECK-SAME: ptr [[F:%.*]]) {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[ADD:%.*]] = add nsw i64 0, 0
+; CHECK-NEXT:    [[SUNKADDR:%.*]] = mul i64 [[ADD]], 2
+; CHECK-NEXT:    [[SUNKADDR1:%.*]] = getelementptr i8, ptr [[F]], i64 [[SUNKADDR]]
+; CHECK-NEXT:    store i8 0, ptr [[SUNKADDR1]], align 1
+; CHECK-NEXT:    ret void
+define void @pr70938(ptr %f) {
+entry:
+  %add = add nsw i32 0, 0
+  %idxprom3 = sext i32 %add to i64
+  %arrayidx4 = getelementptr [2 x [1 x [2 x i8]]], ptr %f, i64 0, i64 %idxprom3
+  %arrayidx8 = getelementptr [2 x i8], ptr %arrayidx4, i64 0, i64 %idxprom3
+  br label %if.end
+
+if.end:                                           ; preds = %entry
+  store i8 0, ptr %arrayidx8, align 1
+  ret void
+}

@@ -2634,6 +2634,15 @@ struct ExtAddrMode : public TargetLowering::AddrMode {
void print(raw_ostream &OS) const;
void dump() const;

void replaceWith(Value *From, Value *To) {
if (BaseReg == From)
Copy link
Contributor

Choose a reason for hiding this comment

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

Are all cases below covered by the one new test?

Copy link
Member Author

Choose a reason for hiding this comment

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

No. I have no idea how to generate tests that would cover all these branches :(

Copy link
Contributor

Choose a reason for hiding this comment

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

Do any of the duplicates provide a test case for the other cases?

Copy link
Member Author

Choose a reason for hiding this comment

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

These two test cases only cover if (ScaledReg == From) ScaledReg = To;.

Copy link
Member Author

Choose a reason for hiding this comment

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

Should we only keep the second case since existing tests do not cover other cases?

Copy link
Contributor

Choose a reason for hiding this comment

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

Sounds reasonable.

@dtcxzyw
Copy link
Member Author

dtcxzyw commented Nov 11, 2023

Ping.

@nikic
Copy link
Contributor

nikic commented Nov 14, 2023

Can you say at which point the sext is assigned to which member of the AddrMode and at which point it is later used again?

Also, does this have any relation to what the MovedAway flag is trying to handle?

@arsenm
Copy link
Contributor

arsenm commented Mar 19, 2024

Needs rebase? Is this still relevant?

Copy link

github-actions bot commented Jan 8, 2025

✅ With the latest revision this PR passed the undef deprecator.

@dtcxzyw dtcxzyw changed the title [CodeGenPrepare] Replace deleted sext instr with the promoted value. [CodeGenPrepare] Replace deleted ext instr with the promoted value. Jan 8, 2025
@dtcxzyw
Copy link
Member Author

dtcxzyw commented Jan 8, 2025

Can you say at which point the sext is assigned to which member of the AddrMode and at which point it is later used again?

For the second case, the zext is assigned to AddrMode.ScaledReg at

TestAddrMode.ScaledReg = AddLHS;
.

After deleting the zext, it is used by

Value *V = AddrMode.ScaledReg;
if (V->getType() == IntPtrTy) {
// done.
} else {
assert(cast<IntegerType>(IntPtrTy)->getBitWidth() <
cast<IntegerType>(V->getType())->getBitWidth() &&
"We can't transform if ScaledReg is too narrow");
V = Builder.CreateTrunc(V, IntPtrTy, "sunkaddr");
}
if (AddrMode.Scale != 1)
V = Builder.CreateMul(V, ConstantInt::get(IntPtrTy, AddrMode.Scale),
"sunkaddr");

Also, does this have any relation to what the MovedAway flag is trying to handle?

MovedAway only avoids using the deleted value in subsequent calls. However, the value may be used by the outer AddressingModeMatcher::matchAddr call.

Copy link
Contributor

@nikic nikic left a comment

Choose a reason for hiding this comment

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

LGTM

@dtcxzyw dtcxzyw merged commit 3c6aa04 into llvm:main Jan 30, 2025
8 checks passed
@dtcxzyw dtcxzyw deleted the fix-cgp-addrmode branch January 30, 2025 00:58
@nikic nikic added this to the LLVM 20.X Release milestone Jan 30, 2025
@nikic
Copy link
Contributor

nikic commented Jan 30, 2025

/cherry-pick 3c6aa04

@llvmbot
Copy link
Member

llvmbot commented Jan 30, 2025

/pull-request #125040

swift-ci pushed a commit to swiftlang/llvm-project that referenced this pull request Feb 1, 2025
…lvm#71058)

This PR replaces the deleted ext with the promoted value in `AddrMode`.
Fixes llvm#70938.

(cherry picked from commit 3c6aa04)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Development

Successfully merging this pull request may close these issues.

Clang crash: Assertion `materialized_use_empty() && "Uses remain when a value is destroyed!"' failed. (since clang-15)
6 participants