This reverts commit r337951.
While that kind of shared constant generally works fine in a MinGW
setting, it broke some cases of inline assembly that worked before:
$ cat const-asm.c
int MULH(int a, int b) {
int rt, dummy;
__asm__ (
"imull %3"
:"=d"(rt), "=a"(dummy)
:"a"(a), "rm"(b)
);
return rt;
}
int func(int a) {
return MULH(a, 1);
}
$ clang -target x86_64-win32-gnu -c const-asm.c -O2
const-asm.c:4:9: error: invalid variant '
00000001'
"imull %3"
^
<inline asm>:1:15: note: instantiated into assembly here
imull __real@
00000001(%rip)
^
A similar error is produced for i686 as well. The same test with a
target of x86_64-win32-msvc or i686-win32-msvc works fine.
llvm-svn: 338018
/// them.
bool HasCOFFAssociativeComdats = false;
+ /// True if this is a non-GNU COFF target. For GNU targets, we don't generate
+ /// constants into comdat sections.
+ bool HasCOFFComdatConstants = false;
+
/// This is the maximum possible length of an instruction, which is needed to
/// compute the size of an inline asm. Defaults to 4.
unsigned MaxInstLength = 4;
bool hasMachoZeroFillDirective() const { return HasMachoZeroFillDirective; }
bool hasMachoTBSSDirective() const { return HasMachoTBSSDirective; }
bool hasCOFFAssociativeComdats() const { return HasCOFFAssociativeComdats; }
+ bool hasCOFFComdatConstants() const { return HasCOFFComdatConstants; }
unsigned getMaxInstLength() const { return MaxInstLength; }
unsigned getMinInstAlignment() const { return MinInstAlignment; }
bool getDollarIsPC() const { return DollarIsPC; }
/// GetCPISymbol - Return the symbol for the specified constant pool entry.
MCSymbol *AsmPrinter::GetCPISymbol(unsigned CPID) const {
- if (getSubtargetInfo().getTargetTriple().isOSWindows()) {
+ if (getSubtargetInfo().getTargetTriple().isKnownWindowsMSVCEnvironment()) {
const MachineConstantPoolEntry &CPE =
MF->getConstantPool()->getConstants()[CPID];
if (!CPE.isMachineConstantPoolEntry()) {
MCSection *TargetLoweringObjectFileCOFF::getSectionForConstant(
const DataLayout &DL, SectionKind Kind, const Constant *C,
unsigned &Align) const {
- if (Kind.isMergeableConst() && C) {
+ if (Kind.isMergeableConst() && C &&
+ getContext().getAsmInfo()->hasCOFFComdatConstants()) {
+ // This creates comdat sections with the given symbol name, but unless
+ // AsmPrinter::GetCPISymbol actually makes the symbol global, the symbol
+ // will be created with a null storage class, which makes GNU binutils
+ // error out.
const unsigned Characteristics = COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
COFF::IMAGE_SCN_MEM_READ |
COFF::IMAGE_SCN_LNK_COMDAT;
// If this is a COFF target, assume that it supports associative comdats. It's
// part of the spec.
HasCOFFAssociativeComdats = true;
+
+ // We can generate constants in comdat sections that can be shared,
+ // but in order not to create null typed symbols, we actually need to
+ // make them global symbols as well.
+ HasCOFFComdatConstants = true;
}
void MCAsmInfoMicrosoft::anchor() {}
// comdats for jump tables, unwind information, and other data associated with
// a function.
HasCOFFAssociativeComdats = false;
+
+ // We don't create constants in comdat sections for MinGW.
+ HasCOFFComdatConstants = false;
}
; RUN: llc < %s -mtriple=aarch64-win32-msvc | FileCheck %s
-; RUN: llc < %s -mtriple=aarch64-win32-gnu | FileCheck %s
+; RUN: llc < %s -mtriple=aarch64-win32-gnu | FileCheck -check-prefix=MINGW %s
define double @double() {
ret double 0x0000000000800000
; CHECK: adrp x8, __real@0000000000800000
; CHECK-NEXT: ldr d0, [x8, __real@0000000000800000]
; CHECK-NEXT: ret
+
+; MINGW: .section .rdata,"dr"
+; MINGW-NEXT: .p2align 3
+; MINGW-NEXT: [[LABEL:\.LC.*]]:
+; MINGW-NEXT: .xword 8388608
+; MINGW: double:
+; MINGW: adrp x8, [[LABEL]]
+; MINGW-NEXT: ldr d0, [x8, [[LABEL]]]
+; MINGW-NEXT: ret
; RUN: llc < %s -mtriple=x86_64-win32 -mattr=sse2 -mattr=avx | FileCheck %s
-; RUN: llc < %s -mtriple=x86_64-win32-gnu -mattr=sse2 -mattr=avx | FileCheck %s
+; RUN: llc < %s -mtriple=x86_64-win32-gnu -mattr=sse2 -mattr=avx | FileCheck -check-prefix=MINGW %s
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-windows-msvc"
; CHECK: movsd __real@0000000000800000(%rip), %xmm0
; CHECK-NEXT: ret
+; MINGW: .section .rdata,"dr"
+; MINGW-NEXT: .p2align 3
+; MINGW-NEXT: [[LABEL:\.LC.*]]:
+; MINGW-NEXT: .quad 8388608
+; MINGW: double:
+; MINGW: movsd [[LABEL]](%rip), %xmm0
+; MINGW-NEXT: ret
+
define <4 x i32> @vec1() {
ret <4 x i32> <i32 3, i32 2, i32 1, i32 0>
}