diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp index 187820717b6fd..1eb610bb281a1 100644 --- a/llvm/lib/CodeGen/CodeGenPrepare.cpp +++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp @@ -2634,6 +2634,18 @@ struct ExtAddrMode : public TargetLowering::AddrMode { void print(raw_ostream &OS) const; void dump() const; + // Replace From in ExtAddrMode with To. + // E.g., SExt insts may be promoted and deleted. We should replace them with + // the promoted values. + 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 +4945,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 6e95c91e73989..a3944ee2040b5 100644 --- a/llvm/test/CodeGen/X86/codegen-prepare-addrmode-sext.ll +++ b/llvm/test/CodeGen/X86/codegen-prepare-addrmode-sext.ll @@ -507,3 +507,26 @@ 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, 1 +; CHECK-NEXT: [[SUNKADDR:%.*]] = mul i64 [[ADD]], 2 +; CHECK-NEXT: [[SUNKADDR1:%.*]] = getelementptr i8, ptr [[F]], i64 [[SUNKADDR]] +; CHECK-NEXT: [[SUNKADDR2:%.*]] = getelementptr i8, ptr [[SUNKADDR1]], i64 1 +; CHECK-NEXT: store i8 0, ptr [[SUNKADDR2]], align 1 +; CHECK-NEXT: ret void +define void @pr70938(ptr %f) { +entry: + %add = add nsw i32 0, 1 + %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 +}