diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -2835,8 +2835,17 @@ if (const ConstantVector *V = dyn_cast(CV)) return emitGlobalConstantVector(DL, V, AP); - // Otherwise, it must be a ConstantExpr. Lower it to an MCExpr, then emit it - // thread the streamer with EmitValue. + // Otherwise, it must be a ConstantExpr. + + // First, try to constant fold floating point constant expressions to a FP + // constant. Those cannot be lowered to MCExpr. + if (CV->getType()->isFloatingPointTy()) { + ConstantFP *New = cast(ConstantFoldConstant(CV, DL)); + if (New) + return emitGlobalConstantFP(New, AP); + } + + // Lower it to an MCExpr, then emit it thread the streamer with EmitValue. const MCExpr *ME = AP.lowerConstant(CV); // Since lowerConstant already folded and got rid of all IR pointer and diff --git a/llvm/test/CodeGen/AArch64/complex-float-constexpr-global-initializer.ll b/llvm/test/CodeGen/AArch64/complex-float-constexpr-global-initializer.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/complex-float-constexpr-global-initializer.ll @@ -0,0 +1,78 @@ +; RUN: llc -o - %s | FileCheck %s + +target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" +target triple = "arm64-apple-ios13.0.0" + +; Make sure complex floating point constant expressions are lowered properly. + +@g = global [1 x <2 x float>] [<2 x float> + bitcast (<1 x i128> to <4 x float>), i32 0)), + float fneg (float extractelement (<4 x float> , i32 1))>] + +define [1 x <2 x float>] @load1() { +; CHECK-LABEL: _load1: +; CHECK-NEXT: .cfi_startproc +; CHECK-NEXT: ; %bb.0: +; CHECK-NEXT: Lloh0: +; CHECK-NEXT: adrp x8, _g@PAGE +; CHECK-NEXT: Lloh1: +; CHECK-NEXT: ldr d0, [x8, _g@PAGEOFF] +; CHECK-NEXT: ret + + %r = load [1 x <2 x float>], [1 x <2 x float>]* @g + ret [1 x <2 x float>] %r +} + +@h = global [1 x <2 x float>] [<2 x float> fadd + (<2 x float> bitcast (<1 x i64> to <2 x float>), + <2 x float> )] + +define [1 x <2 x float>] @load2() { +; CHECK-LABEL: _load2: +; CHECK-NEXT: .cfi_startproc +; CHECK-NEXT: ; %bb.0: +; CHECK-NEXT: Lloh2: +; CHECK-NEXT: adrp x8, _h@PAGE +; CHECK-NEXT: Lloh3: +; CHECK-NEXT: ldr d0, [x8, _h@PAGEOFF] +; CHECK-NEXT: ret + + %r = load [1 x <2 x float>], [1 x <2 x float>]* @h + ret [1 x <2 x float>] %r +} + + + +define [1 x <2 x float>] @promoted() { +; CHECK-LABEL: _promoted: +; CHECK-NEXT: .cfi_startproc +; CHECK-NEXT: ; %bb.0: +; CHECK-NEXT: Lloh4: +; CHECK-NEXT: adrp x8, __PromotedConst@PAGE +; CHECK-NEXT: Lloh5: +; CHECK-NEXT: ldr d0, [x8, __PromotedConst@PAGEOFF] +; CHECK-NEXT: ret + + ret [1 x <2 x float>] [<2 x float> + bitcast (<1 x i128> to <4 x float>), i32 0)), + float fneg (float extractelement (<4 x float> bitcast (<1 x i128> to <4 x float>), i32 1))>] +} + +; CHECK-LABEL: .section __DATA,__data +; CHECK-NEXT: .globl _g ; @g +; CHECK-NEXT: .p2align 3 +; CHECK-NEXT: _g: +; CHECK-NEXT: .long 0x80000001 ; float -1.40129846E-45 +; CHECK-NEXT: .long 0xc1280000 ; float -10.5 + +; CHECK: .globl _h ; @h +; CHECK-NEXT: .p2align 3 +; CHECK-NEXT: _h: +; CHECK-NEXT: .long 0x0000000a ; float 1.40129846E-44 +; CHECK-NEXT: .long 0x41280000 ; float 10.5 + +; CHECK-LABEL: .section __TEXT,__const +; CHECK-NEXT: .p2align 3 ; @_PromotedConst +; CHECK-NEXT: __PromotedConst: +; CHECK-NEXT: .long 0xe4c00000 ; float -2.83341989E+22 +; CHECK-NEXT: .long 0x80000000 ; float -0 diff --git a/llvm/test/CodeGen/X86/complex-float-constexpr-global-initializer.ll b/llvm/test/CodeGen/X86/complex-float-constexpr-global-initializer.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/X86/complex-float-constexpr-global-initializer.ll @@ -0,0 +1,53 @@ +; RUN: llc -o - %s | FileCheck %s + +target triple = "x86_64-apple-darwin" + +; Make sure complex floating point constant expressions are lowered properly. + +@g = global [1 x <2 x float>] [<2 x float> + bitcast (<1 x i128> to <4 x float>), i32 0)), + float fneg (float extractelement (<4 x float> , i32 1))>] + +define [1 x <2 x float>] @load1() { +; CHECK-LABEL: .globl _load1 ## -- Begin function load +; CHECK-NEXT: .p2align 4, 0x90 +; CHECK-NEXT: _load1: ## @load1 +; CHECK-NEXT: .cfi_startproc +; CHECK-NEXT: ## %bb.0: +; CHECK-NEXT: movsd _g(%rip), %xmm0 ## xmm0 = mem[0],zero +; CHECK-NEXT: retq + + %r = load [1 x <2 x float>], [1 x <2 x float>]* @g + ret [1 x <2 x float>] %r +} + +@h = global [1 x <2 x float>] [<2 x float> fadd + (<2 x float> bitcast (<1 x i64> to <2 x float>), + <2 x float> )] + +define [1 x <2 x float>] @load2() { +; CHECK-LABEL: .globl _load2 ## -- Begin function load2 +; CHECK-NEXT: .p2align 4, 0x90 +; CHECK-NEXT: _load2: ## @load2 +; CHECK-NEXT: .cfi_startproc +; CHECK-NEXT: ## %bb.0: +; CHECK-NEXT: movsd _h(%rip), %xmm0 ## xmm0 = mem[0],zero +; CHECK-NEXT: retq + + %r = load [1 x <2 x float>], [1 x <2 x float>]* @h + ret [1 x <2 x float>] %r +} + + +; CHECK-LABEL: .section __DATA,__data +; CHECK-NEXT: .globl _g ## @g +; CHECK-NEXT: .p2align 3 +; CHECK-NEXT: _g: +; CHECK-NEXT: .long 0x80000001 ## float -1.40129846E-45 +; CHECK-NEXT: .long 0xc1280000 ## float -10.5 + +; CHECK: .globl _h ## @h +; CHECK-NEXT: .p2align 3 +; CHECK-NEXT: _h: +; CHECK-NEXT: .long 0x0000000a ## float 1.40129846E-44 +; CHECK-NEXT: .long 0x41280000 ## float 10.5