diff --git a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp index 8e425ddcdada..13335a84f6d9 100644 --- a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp @@ -865,11 +865,12 @@ EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) { // However, if this global is promoted into several functions we must ensure // we don't try and emit duplicate symbols! auto *ACPC = cast(ACPV); - auto *GV = ACPC->getPromotedGlobal(); - if (!EmittedPromotedGlobalLabels.count(GV)) { - MCSymbol *GVSym = getSymbol(GV); - OutStreamer->EmitLabel(GVSym); - EmittedPromotedGlobalLabels.insert(GV); + for (const auto *GV : ACPC->promotedGlobals()) { + if (!EmittedPromotedGlobalLabels.count(GV)) { + MCSymbol *GVSym = getSymbol(GV); + OutStreamer->EmitLabel(GVSym); + EmittedPromotedGlobalLabels.insert(GV); + } } return EmitGlobalConstant(DL, ACPC->getPromotedGlobalInit()); } diff --git a/llvm/lib/Target/ARM/ARMConstantPoolValue.cpp b/llvm/lib/Target/ARM/ARMConstantPoolValue.cpp index 9705c8b718b7..88b3683bd75b 100644 --- a/llvm/lib/Target/ARM/ARMConstantPoolValue.cpp +++ b/llvm/lib/Target/ARM/ARMConstantPoolValue.cpp @@ -140,8 +140,9 @@ ARMConstantPoolConstant::ARMConstantPoolConstant(const Constant *C, ARMConstantPoolConstant::ARMConstantPoolConstant(const GlobalVariable *GV, const Constant *C) : ARMConstantPoolValue((Type *)C->getType(), 0, ARMCP::CPPromotedGlobal, 0, - ARMCP::no_modifier, false), - CVal(C), GVar(GV) {} + ARMCP::no_modifier, false), CVal(C) { + GVars.insert(GV); +} ARMConstantPoolConstant * ARMConstantPoolConstant::Create(const Constant *C, unsigned ID) { @@ -189,7 +190,15 @@ const BlockAddress *ARMConstantPoolConstant::getBlockAddress() const { int ARMConstantPoolConstant::getExistingMachineCPValue(MachineConstantPool *CP, unsigned Alignment) { - return getExistingMachineCPValueImpl(CP, Alignment); + int index = + getExistingMachineCPValueImpl(CP, Alignment); + if (index != -1) { + auto *CPV = static_cast( + CP->getConstants()[index].Val.MachineCPVal); + auto *Constant = cast(CPV); + Constant->GVars.insert(GVars.begin(), GVars.end()); + } + return index; } bool ARMConstantPoolConstant::hasSameValue(ARMConstantPoolValue *ACPV) { @@ -199,6 +208,8 @@ bool ARMConstantPoolConstant::hasSameValue(ARMConstantPoolValue *ACPV) { void ARMConstantPoolConstant::addSelectionDAGCSEId(FoldingSetNodeID &ID) { ID.AddPointer(CVal); + for (const auto *GV : GVars) + ID.AddPointer(GV); ARMConstantPoolValue::addSelectionDAGCSEId(ID); } diff --git a/llvm/lib/Target/ARM/ARMConstantPoolValue.h b/llvm/lib/Target/ARM/ARMConstantPoolValue.h index 61c521581f79..30ce8716c5cb 100644 --- a/llvm/lib/Target/ARM/ARMConstantPoolValue.h +++ b/llvm/lib/Target/ARM/ARMConstantPoolValue.h @@ -15,6 +15,7 @@ #define LLVM_LIB_TARGET_ARM_ARMCONSTANTPOOLVALUE_H #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/SmallPtrSet.h" #include "llvm/CodeGen/MachineConstantPool.h" #include "llvm/Support/Casting.h" #include @@ -80,8 +81,8 @@ protected: for (unsigned i = 0, e = Constants.size(); i != e; ++i) { if (Constants[i].isMachineConstantPoolEntry() && (Constants[i].getAlignment() & AlignMask) == 0) { - ARMConstantPoolValue *CPV = - (ARMConstantPoolValue *)Constants[i].Val.MachineCPVal; + auto *CPV = + static_cast(Constants[i].Val.MachineCPVal); if (Derived *APC = dyn_cast(CPV)) if (cast(this)->equals(APC)) return i; @@ -139,7 +140,7 @@ inline raw_ostream &operator<<(raw_ostream &O, const ARMConstantPoolValue &V) { /// Functions, and BlockAddresses. class ARMConstantPoolConstant : public ARMConstantPoolValue { const Constant *CVal; // Constant being loaded. - const GlobalVariable *GVar = nullptr; + SmallPtrSet GVars; ARMConstantPoolConstant(const Constant *C, unsigned ID, @@ -173,8 +174,9 @@ public: const GlobalValue *getGV() const; const BlockAddress *getBlockAddress() const; - const GlobalVariable *getPromotedGlobal() const { - return dyn_cast_or_null(GVar); + typedef SmallPtrSet::iterator promoted_iterator; + iterator_range promotedGlobals() { + return iterator_range(GVars.begin(), GVars.end()); } const Constant *getPromotedGlobalInit() const { diff --git a/llvm/test/CodeGen/ARM/constantpool-promote-duplicate.ll b/llvm/test/CodeGen/ARM/constantpool-promote-duplicate.ll new file mode 100644 index 000000000000..70c4807a044f --- /dev/null +++ b/llvm/test/CodeGen/ARM/constantpool-promote-duplicate.ll @@ -0,0 +1,21 @@ +; RUN: llc -mtriple=arm-eabi -relocation-model=static -arm-promote-constant < %s | FileCheck %s + +@const1 = private unnamed_addr constant i32 0, align 4 +@const2 = private unnamed_addr constant i32 0, align 4 + +; const1 and const2 both need labels for debug info, but will be coalesced into +; a single constpool entry + +; CHECK-LABEL: @test1 +; CHECK-DAG: const1: +; CHECK-DAG: const2: +; CHECK: .fnend +define void @test1() { + %1 = load i32, i32* @const1, align 4 + call void @a(i32 %1) + %2 = load i32, i32* @const2, align 4 + call void @a(i32 %2) + ret void +} + +declare void @a(i32)