Index: lib/Target/ARM/ARMAsmPrinter.cpp =================================================================== --- lib/Target/ARM/ARMAsmPrinter.cpp +++ lib/Target/ARM/ARMAsmPrinter.cpp @@ -869,11 +869,12 @@ // 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 (auto *GV : ACPC->promotedGlobals()) { + if (!EmittedPromotedGlobalLabels.count(GV)) { + MCSymbol *GVSym = getSymbol(GV); + OutStreamer->EmitLabel(GVSym); + EmittedPromotedGlobalLabels.insert(GV); + } } return EmitGlobalConstant(DL, ACPC->getPromotedGlobalInit()); } Index: lib/Target/ARM/ARMConstantPoolValue.h =================================================================== --- lib/Target/ARM/ARMConstantPoolValue.h +++ 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 @@ -139,7 +140,7 @@ /// 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,12 @@ const GlobalValue *getGV() const; const BlockAddress *getBlockAddress() const; - const GlobalVariable *getPromotedGlobal() const { - return dyn_cast_or_null(GVar); + typedef SmallPtrSet::iterator promoted_iterator; + typedef iterator_range promoted_iterator_range; + promoted_iterator promoted_begin() const { return GVars.begin(); } + promoted_iterator promoted_end() const { return GVars.end(); } + promoted_iterator_range promotedGlobals() { + return promoted_iterator_range(promoted_begin(), promoted_end()); } const Constant *getPromotedGlobalInit() const { Index: lib/Target/ARM/ARMConstantPoolValue.cpp =================================================================== --- lib/Target/ARM/ARMConstantPoolValue.cpp +++ lib/Target/ARM/ARMConstantPoolValue.cpp @@ -140,8 +140,9 @@ 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,14 @@ int ARMConstantPoolConstant::getExistingMachineCPValue(MachineConstantPool *CP, unsigned Alignment) { - return getExistingMachineCPValueImpl(CP, Alignment); + int index = getExistingMachineCPValueImpl(CP, Alignment); + if (index != -1) { + ARMConstantPoolValue *CPV = + (ARMConstantPoolValue*)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 +207,8 @@ void ARMConstantPoolConstant::addSelectionDAGCSEId(FoldingSetNodeID &ID) { ID.AddPointer(CVal); + for (auto GV : GVars) + ID.AddPointer(GV); ARMConstantPoolValue::addSelectionDAGCSEId(ID); } Index: test/CodeGen/ARM/constantpool-promote-global-dbg.ll =================================================================== --- /dev/null +++ test/CodeGen/ARM/constantpool-promote-global-dbg.ll @@ -0,0 +1,49 @@ +; RUN: llc -relocation-model=static -arm-promote-constant < %s | FileCheck %s + +target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64" +target triple = "thumbv7m--linux-gnu" + +@const1 = private unnamed_addr constant i32 0, align 4, !dbg !6 +@const2 = private unnamed_addr constant i32 0, align 4, !dbg !9 + +; 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() #0 { + %1 = load i32, i32* @const1, align 4 + call void @a(i32 %1) #1 + %2 = load i32, i32* @const2, align 4 + call void @a(i32 %2) #1 + ret void +} + +declare void @a(i32) #1 + +attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind } + +!llvm.dbg.cu = !{!2} +!llvm.ident = !{!20, !20} +!llvm.module.flags = !{!21, !22, !23, !24, !25} + +!0 = !DIGlobalVariableExpression(var: !1) +!1 = distinct !DIGlobalVariable(name: "opaque", scope: !2, file: !3, line: 13, type: !8, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "Android clang version 5.0.300080 (based on LLVM 5.0.300080)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5) +!3 = !DIFile(filename: "constpool-promote-global-dbg.c", directory: "/test/CodeGen/ARM/") +!4 = !{} +!5 = !{!6, !9} +!6 = !DIGlobalVariableExpression(var: !7) +!7 = distinct !DIGlobalVariable(name: "const1", scope: !2, file: !3, line: 6, type: !8, isLocal: false, isDefinition: true) +!8 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!9 = !DIGlobalVariableExpression(var: !10) +!10 = distinct !DIGlobalVariable(name: "const2", scope: !2, file: !3, line: 7, type: !8, isLocal: false, isDefinition: true) +!20 = !{!"Android clang version 5.0.300080 (based on LLVM 5.0.300080)"} +!21 = !{i32 2, !"Dwarf Version", i32 4} +!22 = !{i32 2, !"Debug Info Version", i32 3} +!23 = !{i32 1, !"wchar_size", i32 4} +!24 = !{i32 1, !"min_enum_size", i32 4} +!25 = !{i32 1, !"PIC Level", i32 1}