diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp --- a/llvm/lib/CodeGen/CodeGenPrepare.cpp +++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp @@ -3559,10 +3559,15 @@ /// Original Address. Value *Original; + /// Common value among addresses + Value *CommonValue = nullptr; + public: AddressingModeCombiner(const SimplifyQuery &_SQ, Value *OriginalValue) : SQ(_SQ), Original(OriginalValue) {} + ~AddressingModeCombiner() { eraseCommonValueIfDead(); } + /// Get the combined AddrMode const ExtAddrMode &getAddrMode() const { return AddrModes[0]; } @@ -3647,13 +3652,21 @@ if (!initializeMap(Map)) return false; - Value *CommonValue = findCommon(Map); + CommonValue = findCommon(Map); if (CommonValue) AddrModes[0].SetCombinedField(DifferentField, CommonValue, AddrModes); return CommonValue != nullptr; } private: + /// `CommonValue` may be a placeholder inserted by us. + /// If the placeholder is not used, we should remove this dead instruction. + void eraseCommonValueIfDead() { + if (CommonValue && CommonValue->getNumUses() == 0) + if (Instruction *CommonInst = dyn_cast(CommonValue)) + CommonInst->eraseFromParent(); + } + /// Initialize Map with anchor values. For address seen /// we set the value of different field saw in this address. /// At the same time we find a common type for different field we will diff --git a/llvm/test/CodeGen/X86/pr58538.ll b/llvm/test/CodeGen/X86/pr58538.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/X86/pr58538.ll @@ -0,0 +1,29 @@ +; RUN: opt -codegenprepare -mtriple=x86_64 %s -S -o - | FileCheck %s +; RUN: opt -codegenprepare -mtriple=i386 %s -S -o - | FileCheck %s + +define i32 @f(i32 %0) { +; CHECK-LABEL: @f +; CHECK: BB: +; CHECK: %P0 = alloca i32, i32 8, align 4 +; CHECK: %P1 = getelementptr i32, ptr %P0, i32 1 +; CHECK: %1 = icmp eq i32 %0, 0 +; CHECK: %P2 = getelementptr i1, ptr %P1, i1 %1 +; CHECK: %2 = icmp eq i32 %0, 0 +; CHECK: %P3 = select i1 %2, ptr %P1, ptr %P2 +; CHECK: %L1 = load i32, ptr %P3, align 4 +; CHECK: ret i32 %L1 +BB: + %P0 = alloca i32, i32 8 + %P1 = getelementptr i32, ptr %P0, i32 1 + %B0 = icmp eq i32 %0, 0 + br label %BB1 + +BB1: ; preds = %BB1, %BB + %P2 = getelementptr i1, ptr %P1, i1 %B0 + br i1 false, label %BB1, label %BB2 + +BB2: ; preds = %BB1 + %P3 = select i1 %B0, ptr %P1, ptr %P2 + %L1 = load i32, ptr %P3 + ret i32 %L1 +}