[AArch64] Materialize FP constant in code for large code model
When using the large code model with FastISel (for example via clang -O0 which adds the optnone attribute), FP constants could still be materialized using adrp + ldr. Unconditionally enable the existing path for MachO to materialize the constant in code. For testing, restore literal_pools_float.ll to exercise the constant pool and add two optnone-functions that return a float and a double, respectively. Consolidate fpimm.ll and add a new fast-isel-fpimm.ll to check the code paths taken with FastISel. Differential Revision: https://reviews.llvm.org/D99607
This commit is contained in:
parent
90af134473
commit
6415f424bc
@ -404,8 +404,8 @@ unsigned AArch64FastISel::materializeFP(const ConstantFP *CFP, MVT VT) {
|
||||
return fastEmitInst_i(Opc, TLI.getRegClassFor(VT), Imm);
|
||||
}
|
||||
|
||||
// For the MachO large code model materialize the FP constant in code.
|
||||
if (Subtarget->isTargetMachO() && TM.getCodeModel() == CodeModel::Large) {
|
||||
// For the large code model materialize the FP constant in code.
|
||||
if (TM.getCodeModel() == CodeModel::Large) {
|
||||
unsigned Opc1 = Is64Bit ? AArch64::MOVi64imm : AArch64::MOVi32imm;
|
||||
const TargetRegisterClass *RC = Is64Bit ?
|
||||
&AArch64::GPR64RegClass : &AArch64::GPR32RegClass;
|
||||
|
||||
20
llvm/test/CodeGen/AArch64/fast-isel-fpimm.ll
Normal file
20
llvm/test/CodeGen/AArch64/fast-isel-fpimm.ll
Normal file
@ -0,0 +1,20 @@
|
||||
; RUN: llc -mtriple=aarch64-linux-gnu -code-model=large -fast-isel -fast-isel-abort=1 -verify-machineinstrs < %s | FileCheck %s
|
||||
; RUN: llc -mtriple=aarch64-apple-darwin -code-model=large -fast-isel -fast-isel-abort=1 -verify-machineinstrs < %s | FileCheck %s
|
||||
|
||||
; CHECK-LABEL: check_float2
|
||||
; CHECK: mov [[REG:w[0-9]+]], #4059
|
||||
; CHECK: movk [[REG]], #16457, lsl #16
|
||||
; CHECK-NEXT: fmov {{s[0-9]+}}, [[REG]]
|
||||
define float @check_float2() {
|
||||
ret float 3.14159274101257324218750
|
||||
}
|
||||
|
||||
; CHECK-LABEL: check_double2
|
||||
; CHECK: mov [[REG:x[0-9]+]], #11544
|
||||
; CHECK-NEXT: movk [[REG]], #21572, lsl #16
|
||||
; CHECK-NEXT: movk [[REG]], #8699, lsl #32
|
||||
; CHECK-NEXT: movk [[REG]], #16393, lsl #48
|
||||
; LARGE-NEXT: fmov {{d[0-9]+}}, [[REG]]
|
||||
define double @check_double2() {
|
||||
ret double 3.1415926535897931159979634685441851615905761718750
|
||||
}
|
||||
@ -1,49 +1,39 @@
|
||||
; RUN: llc -mtriple=aarch64-linux-gnu -verify-machineinstrs < %s | FileCheck %s
|
||||
; RUN: llc -mtriple=aarch64-apple-darwin -code-model=large -verify-machineinstrs < %s | FileCheck %s --check-prefix=LARGE
|
||||
; RUN: llc -mtriple=aarch64-apple-darwin -code-model=large -fast-isel -fast-isel-abort=1 -verify-machineinstrs < %s | FileCheck %s --check-prefix=LARGE
|
||||
; RUN: llc -mtriple=aarch64-none-eabi -code-model=tiny -verify-machineinstrs < %s | FileCheck %s --check-prefix=TINY
|
||||
; RUN: llc -mtriple=aarch64-apple-darwin -code-model=large -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,LARGE
|
||||
; RUN: llc -mtriple=aarch64-none-eabi -code-model=tiny -verify-machineinstrs < %s | FileCheck %s
|
||||
|
||||
@varf32 = global float 0.0
|
||||
@varf64 = global double 0.0
|
||||
|
||||
define void @check_float() {
|
||||
; CHECK-LABEL: check_float:
|
||||
; TINY-LABEL: check_float:
|
||||
|
||||
%val = load float, float* @varf32
|
||||
%newval1 = fadd float %val, 8.5
|
||||
store volatile float %newval1, float* @varf32
|
||||
; CHECK-DAG: fmov {{s[0-9]+}}, #8.5
|
||||
; TINY-DAG: fmov {{s[0-9]+}}, #8.5
|
||||
|
||||
%newval2 = fadd float %val, 128.0
|
||||
store volatile float %newval2, float* @varf32
|
||||
; CHECK-DAG: mov [[W128:w[0-9]+]], #1124073472
|
||||
; CHECK-DAG: fmov {{s[0-9]+}}, [[W128]]
|
||||
; TINY-DAG: mov [[W128:w[0-9]+]], #1124073472
|
||||
; TINY-DAG: fmov {{s[0-9]+}}, [[W128]]
|
||||
|
||||
; CHECK: ret
|
||||
; TINY: ret
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @check_double() {
|
||||
; CHECK-LABEL: check_double:
|
||||
; TINY-LABEL: check_double:
|
||||
|
||||
%val = load double, double* @varf64
|
||||
%newval1 = fadd double %val, 8.5
|
||||
store volatile double %newval1, double* @varf64
|
||||
; CHECK-DAG: fmov {{d[0-9]+}}, #8.5
|
||||
; TINY-DAG: fmov {{d[0-9]+}}, #8.5
|
||||
|
||||
%newval2 = fadd double %val, 128.0
|
||||
store volatile double %newval2, double* @varf64
|
||||
; CHECK-DAG: mov [[X128:x[0-9]+]], #4638707616191610880
|
||||
; CHECK-DAG: fmov {{d[0-9]+}}, [[X128]]
|
||||
; TINY-DAG: mov [[X128:x[0-9]+]], #4638707616191610880
|
||||
; TINY-DAG: fmov {{d[0-9]+}}, [[X128]]
|
||||
|
||||
; 64-bit ORR followed by MOVK.
|
||||
; CHECK-DAG: mov [[XFP0:x[0-9]+]], #1082331758844
|
||||
@ -53,17 +43,13 @@ define void @check_double() {
|
||||
store volatile double %newval3, double* @varf64
|
||||
|
||||
; CHECK: ret
|
||||
; TINY: ret
|
||||
ret void
|
||||
}
|
||||
|
||||
; LARGE-LABEL: check_float2
|
||||
; LARGE: mov [[REG:w[0-9]+]], #4059
|
||||
; LARGE-NEXT: movk [[REG]], #16457, lsl #16
|
||||
; LARGE-NEXT: fmov s0, [[REG]]
|
||||
; TINY-LABEL: check_float2
|
||||
; TINY: mov [[REG:w[0-9]+]], #4059
|
||||
; TINY-NEXT: movk [[REG]], #16457, lsl #16
|
||||
; CHECK-LABEL: check_float2
|
||||
; CHECK: mov [[REG:w[0-9]+]], #4059
|
||||
; CHECK-NEXT: movk [[REG]], #16457, lsl #16
|
||||
; CHECK-NEXT: fmov {{s[0-9]+}}, [[REG]]
|
||||
define float @check_float2() {
|
||||
ret float 3.14159274101257324218750
|
||||
}
|
||||
@ -73,9 +59,7 @@ define float @check_float2() {
|
||||
; LARGE-NEXT: movk [[REG]], #21572, lsl #16
|
||||
; LARGE-NEXT: movk [[REG]], #8699, lsl #32
|
||||
; LARGE-NEXT: movk [[REG]], #16393, lsl #48
|
||||
; LARGE-NEXT: fmov d0, [[REG]]
|
||||
; TINY-LABEL: check_double2
|
||||
; TINY: ldr d0, .LCPI3_0
|
||||
; LARGE-NEXT: fmov {{d[0-9]+}}, [[REG]]
|
||||
define double @check_double2() {
|
||||
ret double 3.1415926535897931159979634685441851615905761718750
|
||||
}
|
||||
|
||||
@ -8,21 +8,23 @@
|
||||
@varfloat = dso_local global float 0.0
|
||||
@vardouble = dso_local global double 0.0
|
||||
|
||||
define dso_local void @floating_lits() {
|
||||
define dso_local void @floating_lits() optsize {
|
||||
; CHECK-LABEL: floating_lits:
|
||||
|
||||
%floatval = load float, float* @varfloat
|
||||
%newfloat = fadd float %floatval, 128.0
|
||||
; CHECK: mov [[W128:w[0-9]+]], #1124073472
|
||||
; CHECK: fmov [[LIT128:s[0-9]+]], [[W128]]
|
||||
%newfloat = fadd float %floatval, 511.0
|
||||
; CHECK: adrp x[[LITBASE:[0-9]+]], [[CURLIT:.LCPI[0-9]+_[0-9]+]]
|
||||
; CHECK: ldr [[LIT128:s[0-9]+]], [x[[LITBASE]], {{#?}}:lo12:[[CURLIT]]]
|
||||
; CHECK-NOFP-NOT: ldr {{s[0-9]+}},
|
||||
|
||||
; CHECK-TINY: mov [[W128:w[0-9]+]], #1124073472
|
||||
; CHECK-TINE: fmov [[LIT128:s[0-9]+]], [[W128]]
|
||||
; CHECK-TINY: ldr [[LIT128:s[0-9]+]], [[CURLIT:.LCPI[0-9]+_[0-9]+]]
|
||||
; CHECK-NOFP-TINY-NOT: ldr {{s[0-9]+}},
|
||||
|
||||
; CHECK-LARGE: mov [[W128:w[0-9]+]], #1124073472
|
||||
; CHECK-LARGE: fmov [[LIT128:s[0-9]+]], [[W128]]
|
||||
; CHECK-LARGE: movz x[[LITADDR:[0-9]+]], #:abs_g0_nc:[[CURLIT:.LCPI[0-9]+_[0-9]+]]
|
||||
; CHECK-LARGE: movk x[[LITADDR]], #:abs_g1_nc:[[CURLIT]]
|
||||
; CHECK-LARGE: movk x[[LITADDR]], #:abs_g2_nc:[[CURLIT]]
|
||||
; CHECK-LARGE: movk x[[LITADDR]], #:abs_g3:[[CURLIT]]
|
||||
; CHECK-LARGE: ldr {{s[0-9]+}}, [x[[LITADDR]]]
|
||||
; CHECK-LARGE: fadd
|
||||
; CHECK-NOFP-LARGE-NOT: ldr {{s[0-9]+}},
|
||||
; CHECK-NOFP-LARGE-NOT: fadd
|
||||
@ -30,20 +32,17 @@ define dso_local void @floating_lits() {
|
||||
store float %newfloat, float* @varfloat
|
||||
|
||||
%doubleval = load double, double* @vardouble
|
||||
%newdouble = fadd double %doubleval, 129.0
|
||||
%newdouble = fadd double %doubleval, 511.0
|
||||
; CHECK: adrp x[[LITBASE:[0-9]+]], [[CURLIT:.LCPI[0-9]+_[0-9]+]]
|
||||
; CHECK: ldr [[LIT129:d[0-9]+]], [x[[LITBASE]], {{#?}}:lo12:[[CURLIT]]]
|
||||
; CHECK-NOFP-NOT: ldr {{d[0-9]+}},
|
||||
; CHECK: mov [[W129:x[0-9]+]], #35184372088832
|
||||
; CHECK: movk [[W129]], #16480, lsl #48
|
||||
; CHECK: fmov {{d[0-9]+}}, [[W129]]
|
||||
; CHECK-NOFP-NOT: fadd
|
||||
|
||||
; CHECK-TINY: mov [[W129:x[0-9]+]], #35184372088832
|
||||
; CHECK-TINY: movk [[W129]], #16480, lsl #48
|
||||
; CHECK-TINY: fmov {{d[0-9]+}}, [[W129]]
|
||||
; CHECK-TINY: ldr [[LIT129:d[0-9]+]], [[CURLIT:.LCPI[0-9]+_[0-9]+]]
|
||||
; CHECK-NOFP-TINY-NOT: ldr {{d[0-9]+}},
|
||||
; CHECK-NOFP-TINY-NOT: fadd
|
||||
|
||||
; CHECK-LARGE: movz x[[LITADDR:[0-9]+]], #:abs_g0_nc:[[CURLIT:vardouble]]
|
||||
; CHECK-LARGE: movz x[[LITADDR:[0-9]+]], #:abs_g0_nc:[[CURLIT:.LCPI[0-9]+_[0-9]+]]
|
||||
; CHECK-LARGE: movk x[[LITADDR]], #:abs_g1_nc:[[CURLIT]]
|
||||
; CHECK-LARGE: movk x[[LITADDR]], #:abs_g2_nc:[[CURLIT]]
|
||||
; CHECK-LARGE: movk x[[LITADDR]], #:abs_g3:[[CURLIT]]
|
||||
@ -54,3 +53,27 @@ define dso_local void @floating_lits() {
|
||||
|
||||
ret void
|
||||
}
|
||||
|
||||
define dso_local float @float_ret_optnone() optnone noinline {
|
||||
; CHECK-LABEL: float_ret_optnone:
|
||||
|
||||
ret float 0x3FB99999A0000000
|
||||
; CHECK: adrp x[[LITBASE:[0-9]+]], [[CURLIT:.LCPI[0-9]+_[0-9]+]]
|
||||
; CHECK: ldr [[LIT128:s[0-9]+]], [x[[LITBASE]], {{#?}}:lo12:[[CURLIT]]]
|
||||
|
||||
; In the large code model, FastISel cannot load from the constant pool.
|
||||
; CHECK-LARGE-NOT: adrp
|
||||
; CHECK-LARGE-NOT: ldr
|
||||
}
|
||||
|
||||
define dso_local double @double_ret_optnone() optnone noinline {
|
||||
; CHECK-LABEL: double_ret_optnone:
|
||||
|
||||
ret double 0.1
|
||||
; CHECK: adrp x[[LITBASE:[0-9]+]], [[CURLIT:.LCPI[0-9]+_[0-9]+]]
|
||||
; CHECK: ldr [[LIT128:d[0-9]+]], [x[[LITBASE]], {{#?}}:lo12:[[CURLIT]]]
|
||||
|
||||
; In the large code model, FastISel cannot load from the constant pool.
|
||||
; CHECK-LARGE-NOT: adrp
|
||||
; CHECK-LARGE-NOT: ldr
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user