[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:
Jonas Hahnfeld
2021-03-30 18:28:54 +02:00
parent 90af134473
commit 6415f424bc
4 changed files with 68 additions and 41 deletions

View File

@@ -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;

View 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
}

View File

@@ -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
}

View File

@@ -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
}