diff --git a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp index 082c8c1124be7c..d6f14c2e613113 100644 --- a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp +++ b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp @@ -4386,54 +4386,55 @@ AArch64InstructionSelector::emitConstantPoolEntry(const Constant *CPVal, MachineInstr *AArch64InstructionSelector::emitLoadFromConstantPool( const Constant *CPVal, MachineIRBuilder &MIRBuilder) const { - auto &MF = MIRBuilder.getMF(); - unsigned CPIdx = emitConstantPoolEntry(CPVal, MF); - - auto Adrp = - MIRBuilder.buildInstr(AArch64::ADRP, {&AArch64::GPR64RegClass}, {}) - .addConstantPoolIndex(CPIdx, 0, AArch64II::MO_PAGE); - - MachineInstr *LoadMI = nullptr; - MachinePointerInfo PtrInfo = MachinePointerInfo::getConstantPool(MF); + const TargetRegisterClass *RC; + unsigned Opc; + bool IsTiny = TM.getCodeModel() == CodeModel::Tiny; unsigned Size = MIRBuilder.getDataLayout().getTypeStoreSize(CPVal->getType()); switch (Size) { case 16: - LoadMI = - &*MIRBuilder - .buildInstr(AArch64::LDRQui, {&AArch64::FPR128RegClass}, {Adrp}) - .addConstantPoolIndex(CPIdx, 0, - AArch64II::MO_PAGEOFF | AArch64II::MO_NC); + RC = &AArch64::FPR128RegClass; + Opc = IsTiny ? AArch64::LDRQl : AArch64::LDRQui; break; case 8: - LoadMI = - &*MIRBuilder - .buildInstr(AArch64::LDRDui, {&AArch64::FPR64RegClass}, {Adrp}) - .addConstantPoolIndex(CPIdx, 0, - AArch64II::MO_PAGEOFF | AArch64II::MO_NC); + RC = &AArch64::FPR64RegClass; + Opc = IsTiny ? AArch64::LDRDl : AArch64::LDRDui; break; case 4: - LoadMI = - &*MIRBuilder - .buildInstr(AArch64::LDRSui, {&AArch64::FPR32RegClass}, {Adrp}) - .addConstantPoolIndex(CPIdx, 0, - AArch64II::MO_PAGEOFF | AArch64II::MO_NC); + RC = &AArch64::FPR32RegClass; + Opc = IsTiny ? AArch64::LDRSl : AArch64::LDRSui; break; case 2: - LoadMI = - &*MIRBuilder - .buildInstr(AArch64::LDRHui, {&AArch64::FPR16RegClass}, {Adrp}) - .addConstantPoolIndex(CPIdx, 0, - AArch64II::MO_PAGEOFF | AArch64II::MO_NC); + RC = &AArch64::FPR16RegClass; + Opc = AArch64::LDRHui; break; default: LLVM_DEBUG(dbgs() << "Could not load from constant pool of type " << *CPVal->getType()); return nullptr; } + + MachineInstr *LoadMI = nullptr; + auto &MF = MIRBuilder.getMF(); + unsigned CPIdx = emitConstantPoolEntry(CPVal, MF); + if (IsTiny && (Size == 16 || Size == 8 || Size == 4)) { + // Use load(literal) for tiny code model. + LoadMI = &*MIRBuilder.buildInstr(Opc, {RC}, {}).addConstantPoolIndex(CPIdx); + } else { + auto Adrp = + MIRBuilder.buildInstr(AArch64::ADRP, {&AArch64::GPR64RegClass}, {}) + .addConstantPoolIndex(CPIdx, 0, AArch64II::MO_PAGE); + + LoadMI = &*MIRBuilder.buildInstr(Opc, {RC}, {Adrp}) + .addConstantPoolIndex( + CPIdx, 0, AArch64II::MO_PAGEOFF | AArch64II::MO_NC); + + constrainSelectedInstRegOperands(*Adrp, TII, TRI, RBI); + } + + MachinePointerInfo PtrInfo = MachinePointerInfo::getConstantPool(MF); LoadMI->addMemOperand(MF, MF.getMachineMemOperand(PtrInfo, MachineMemOperand::MOLoad, Size, Align(Size))); - constrainSelectedInstRegOperands(*Adrp, TII, TRI, RBI); constrainSelectedInstRegOperands(*LoadMI, TII, TRI, RBI); return LoadMI; } diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-imm.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-imm.mir index 606c673cc28031..0e0ed70fb955f0 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/select-imm.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-imm.mir @@ -1,5 +1,6 @@ # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py # RUN: llc -O0 -mtriple=aarch64-- -run-pass=instruction-select -global-isel-abort=1 -verify-machineinstrs %s -o - | FileCheck %s +# RUN: llc -O0 -mtriple=aarch64-- -run-pass=instruction-select -global-isel-abort=1 --code-model=tiny -verify-machineinstrs %s -o - | FileCheck -check-prefix=CHECK-TINY %s --- | target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" @@ -30,8 +31,15 @@ body: | liveins: $w0, $w1 ; CHECK-LABEL: name: imm_s32_gpr - ; CHECK: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm -1234 - ; CHECK: $w0 = COPY [[MOVi32imm]] + ; CHECK: liveins: $w0, $w1 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm -1234 + ; CHECK-NEXT: $w0 = COPY [[MOVi32imm]] + ; CHECK-TINY-LABEL: name: imm_s32_gpr + ; CHECK-TINY: liveins: $w0, $w1 + ; CHECK-TINY-NEXT: {{ $}} + ; CHECK-TINY-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm -1234 + ; CHECK-TINY-NEXT: $w0 = COPY [[MOVi32imm]] %0(s32) = G_CONSTANT i32 -1234 $w0 = COPY %0(s32) ... @@ -50,9 +58,17 @@ body: | liveins: $w0, $w1 ; CHECK-LABEL: name: imm_s64_gpr - ; CHECK: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1234 - ; CHECK: [[SUBREG_TO_REG:%[0-9]+]]:gpr64all = SUBREG_TO_REG 0, [[MOVi32imm]], %subreg.sub_32 - ; CHECK: $x0 = COPY [[SUBREG_TO_REG]] + ; CHECK: liveins: $w0, $w1 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1234 + ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64all = SUBREG_TO_REG 0, [[MOVi32imm]], %subreg.sub_32 + ; CHECK-NEXT: $x0 = COPY [[SUBREG_TO_REG]] + ; CHECK-TINY-LABEL: name: imm_s64_gpr + ; CHECK-TINY: liveins: $w0, $w1 + ; CHECK-TINY-NEXT: {{ $}} + ; CHECK-TINY-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1234 + ; CHECK-TINY-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gpr64all = SUBREG_TO_REG 0, [[MOVi32imm]], %subreg.sub_32 + ; CHECK-TINY-NEXT: $x0 = COPY [[SUBREG_TO_REG]] %0(s64) = G_CONSTANT i64 1234 $x0 = COPY %0(s64) ... @@ -69,12 +85,22 @@ body: | liveins: $d0 ; CHECK-LABEL: name: test_f64_cp - ; CHECK: [[COPY:%[0-9]+]]:fpr64 = COPY $d0 - ; CHECK: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) %const.0 - ; CHECK: [[LDRDui:%[0-9]+]]:fpr64 = LDRDui [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) %const.0 - ; CHECK: [[FADDDrr:%[0-9]+]]:fpr64 = nofpexcept FADDDrr [[COPY]], [[LDRDui]] - ; CHECK: $d0 = COPY [[FADDDrr]] - ; CHECK: RET_ReallyLR implicit $d0 + ; CHECK: liveins: $d0 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr64 = COPY $d0 + ; CHECK-NEXT: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) %const.0 + ; CHECK-NEXT: [[LDRDui:%[0-9]+]]:fpr64 = LDRDui [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) %const.0 :: (load (s64) from constant-pool) + ; CHECK-NEXT: %2:fpr64 = nofpexcept FADDDrr [[COPY]], [[LDRDui]] + ; CHECK-NEXT: $d0 = COPY %2 + ; CHECK-NEXT: RET_ReallyLR implicit $d0 + ; CHECK-TINY-LABEL: name: test_f64_cp + ; CHECK-TINY: liveins: $d0 + ; CHECK-TINY-NEXT: {{ $}} + ; CHECK-TINY-NEXT: [[COPY:%[0-9]+]]:fpr64 = COPY $d0 + ; CHECK-TINY-NEXT: [[LDRDl:%[0-9]+]]:fpr64 = LDRDl %const.0 :: (load (s64) from constant-pool) + ; CHECK-TINY-NEXT: %2:fpr64 = nofpexcept FADDDrr [[COPY]], [[LDRDl]] + ; CHECK-TINY-NEXT: $d0 = COPY %2 + ; CHECK-TINY-NEXT: RET_ReallyLR implicit $d0 %0:fpr(s64) = COPY $d0 %1:fpr(s64) = G_FCONSTANT double 0x3FEFF7CED916872B %2:fpr(s64) = G_FADD %0, %1 @@ -94,12 +120,22 @@ body: | liveins: $s0 ; CHECK-LABEL: name: test_f32_cp_optsize - ; CHECK: [[COPY:%[0-9]+]]:fpr32 = COPY $s0 - ; CHECK: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) %const.0 - ; CHECK: [[LDRSui:%[0-9]+]]:fpr32 = LDRSui [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) %const.0 - ; CHECK: [[FADDSrr:%[0-9]+]]:fpr32 = nofpexcept FADDSrr [[COPY]], [[LDRSui]] - ; CHECK: $s0 = COPY [[FADDSrr]] - ; CHECK: RET_ReallyLR implicit $s0 + ; CHECK: liveins: $s0 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr32 = COPY $s0 + ; CHECK-NEXT: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) %const.0 + ; CHECK-NEXT: [[LDRSui:%[0-9]+]]:fpr32 = LDRSui [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) %const.0 :: (load (s32) from constant-pool) + ; CHECK-NEXT: %2:fpr32 = nofpexcept FADDSrr [[COPY]], [[LDRSui]] + ; CHECK-NEXT: $s0 = COPY %2 + ; CHECK-NEXT: RET_ReallyLR implicit $s0 + ; CHECK-TINY-LABEL: name: test_f32_cp_optsize + ; CHECK-TINY: liveins: $s0 + ; CHECK-TINY-NEXT: {{ $}} + ; CHECK-TINY-NEXT: [[COPY:%[0-9]+]]:fpr32 = COPY $s0 + ; CHECK-TINY-NEXT: [[LDRSl:%[0-9]+]]:fpr32 = LDRSl %const.0 :: (load (s32) from constant-pool) + ; CHECK-TINY-NEXT: %2:fpr32 = nofpexcept FADDSrr [[COPY]], [[LDRSl]] + ; CHECK-TINY-NEXT: $s0 = COPY %2 + ; CHECK-TINY-NEXT: RET_ReallyLR implicit $s0 %0:fpr(s32) = COPY $s0 %1:fpr(s32) = G_FCONSTANT float 0x3FDB267DE0000000 %2:fpr(s32) = G_FADD %0, %1 @@ -119,12 +155,22 @@ body: | liveins: $s0 ; CHECK-LABEL: name: test_f32_cp_minsize - ; CHECK: [[COPY:%[0-9]+]]:fpr32 = COPY $s0 - ; CHECK: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) %const.0 - ; CHECK: [[LDRSui:%[0-9]+]]:fpr32 = LDRSui [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) %const.0 - ; CHECK: [[FADDSrr:%[0-9]+]]:fpr32 = nofpexcept FADDSrr [[COPY]], [[LDRSui]] - ; CHECK: $s0 = COPY [[FADDSrr]] - ; CHECK: RET_ReallyLR implicit $s0 + ; CHECK: liveins: $s0 + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr32 = COPY $s0 + ; CHECK-NEXT: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) %const.0 + ; CHECK-NEXT: [[LDRSui:%[0-9]+]]:fpr32 = LDRSui [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) %const.0 :: (load (s32) from constant-pool) + ; CHECK-NEXT: %2:fpr32 = nofpexcept FADDSrr [[COPY]], [[LDRSui]] + ; CHECK-NEXT: $s0 = COPY %2 + ; CHECK-NEXT: RET_ReallyLR implicit $s0 + ; CHECK-TINY-LABEL: name: test_f32_cp_minsize + ; CHECK-TINY: liveins: $s0 + ; CHECK-TINY-NEXT: {{ $}} + ; CHECK-TINY-NEXT: [[COPY:%[0-9]+]]:fpr32 = COPY $s0 + ; CHECK-TINY-NEXT: [[LDRSl:%[0-9]+]]:fpr32 = LDRSl %const.0 :: (load (s32) from constant-pool) + ; CHECK-TINY-NEXT: %2:fpr32 = nofpexcept FADDSrr [[COPY]], [[LDRSl]] + ; CHECK-TINY-NEXT: $s0 = COPY %2 + ; CHECK-TINY-NEXT: RET_ReallyLR implicit $s0 %0:fpr(s32) = COPY $s0 %1:fpr(s32) = G_FCONSTANT float 0x3FDB267DE0000000 %2:fpr(s32) = G_FADD %0, %1