From 0f8bc043c5025d93f7ba3d435651d8077684981a Mon Sep 17 00:00:00 2001 From: Juergen Ributzka Date: Wed, 13 Aug 2014 22:25:35 +0000 Subject: [PATCH] [FastISel][X86] Add large code model support for materializing floating-point constants. In the large code model for X86 floating-point constants are placed in the constant pool and materialized by loading from it. Since the constant pool could be far away, a PC relative load might not work. Therefore we first materialize the address of the constant pool with a movabsq and then load from there the floating-point value. Fixes . llvm-svn: 215595 --- llvm/lib/Target/X86/X86FastISel.cpp | 18 +++++++++- llvm/test/CodeGen/X86/fast-isel-constpool.ll | 36 +++++++++++--------- 2 files changed, 37 insertions(+), 17 deletions(-) diff --git a/llvm/lib/Target/X86/X86FastISel.cpp b/llvm/lib/Target/X86/X86FastISel.cpp index f42465d14ce1..16e57a0f6f52 100644 --- a/llvm/lib/Target/X86/X86FastISel.cpp +++ b/llvm/lib/Target/X86/X86FastISel.cpp @@ -3163,7 +3163,8 @@ unsigned X86FastISel::X86MaterializeFP(const ConstantFP *CFP, MVT VT) { return TargetMaterializeFloatZero(CFP); // Can't handle alternate code models yet. - if (TM.getCodeModel() != CodeModel::Small) + CodeModel::Model CM = TM.getCodeModel(); + if (CM != CodeModel::Small && CM != CodeModel::Large) return 0; // Get opcode and regclass of the output for the given load instruction. @@ -3219,6 +3220,21 @@ unsigned X86FastISel::X86MaterializeFP(const ConstantFP *CFP, MVT VT) { unsigned CPI = MCP.getConstantPoolIndex(CFP, Align); unsigned ResultReg = createResultReg(RC); + if (CM == CodeModel::Large) { + unsigned AddrReg = createResultReg(&X86::GR64RegClass); + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(X86::MOV64ri), + AddrReg) + .addConstantPoolIndex(CPI, 0, OpFlag); + MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, + TII.get(Opc), ResultReg); + addDirectMem(MIB, AddrReg); + MachineMemOperand *MMO = FuncInfo.MF->getMachineMemOperand( + MachinePointerInfo::getConstantPool(), MachineMemOperand::MOLoad, + TM.getSubtargetImpl()->getDataLayout()->getPointerSize(), Align); + MIB->addMemOperand(*FuncInfo.MF, MMO); + return ResultReg; + } + addConstantPoolReference(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc), ResultReg), CPI, PICBase, OpFlag); diff --git a/llvm/test/CodeGen/X86/fast-isel-constpool.ll b/llvm/test/CodeGen/X86/fast-isel-constpool.ll index bbbaeb233919..4e6f7c0f9e8e 100644 --- a/llvm/test/CodeGen/X86/fast-isel-constpool.ll +++ b/llvm/test/CodeGen/X86/fast-isel-constpool.ll @@ -1,19 +1,23 @@ -; RUN: llc < %s -fast-isel | FileCheck %s -; CHECK: LCPI0_0(%rip) +; RUN: llc -mtriple=x86_64-apple-darwin -fast-isel -code-model=small < %s | FileCheck %s +; RUN: llc -mtriple=x86_64-apple-darwin -fast-isel -code-model=large < %s | FileCheck %s --check-prefix=LARGE -; Make sure fast isel uses rip-relative addressing when required. -target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" -target triple = "x86_64-apple-darwin9.0" +; Make sure fast isel uses rip-relative addressing for the small code model. +define float @constpool_float(float %x) { +; CHECK-LABEL: constpool_float +; CHECK: LCPI0_0(%rip) -define i32 @f0(double %x) nounwind { -entry: - %retval = alloca i32 ; [#uses=2] - %x.addr = alloca double ; [#uses=2] - store double %x, double* %x.addr - %tmp = load double* %x.addr ; [#uses=1] - %cmp = fcmp olt double %tmp, 8.500000e-01 ; [#uses=1] - %conv = zext i1 %cmp to i32 ; [#uses=1] - store i32 %conv, i32* %retval - %0 = load i32* %retval ; [#uses=1] - ret i32 %0 +; LARGE-LABEL: constpool_float +; LARGE: movabsq $LCPI0_0, %rax + %1 = fadd float %x, 16.50e+01 + ret float %1 +} + +define double @constpool_double(double %x) nounwind { +; CHECK-LABEL: constpool_double +; CHECK: LCPI1_0(%rip) + +; LARGE-LABEL: constpool_double +; LARGE: movabsq $LCPI1_0, %rax + %1 = fadd double %x, 8.500000e-01 + ret double %1 }