[llvm] [AArch64][GlobalISel] Use GPR for illegal fconstants and extend < 32 bit GPR constants to 32 bits (PR #178692)
Ryan Cowan via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 2 06:47:16 PST 2026
https://github.com/HolyMolyCowMan updated https://github.com/llvm/llvm-project/pull/178692
>From 342b9f9e41e002c56726583e48811cd490d3e691 Mon Sep 17 00:00:00 2001
From: Ryan Cowan <ryan.cowan at arm.com>
Date: Wed, 28 Jan 2026 14:56:54 +0000
Subject: [PATCH 1/5] [AArch64][GlobalISel] Use GPR for illegal fconstants and
extend < 32 bit GPR constants to 32 bits
---
.../Target/AArch64/AArch64ISelLowering.cpp | 2 +-
.../AArch64/GISel/AArch64GlobalISelUtils.cpp | 4 +-
.../GISel/AArch64InstructionSelector.cpp | 34 +++--
.../AArch64/GISel/AArch64RegisterBankInfo.cpp | 76 ++++++++++
.../GlobalISel/regbankselect-build-vector.mir | 45 ++++--
.../test/CodeGen/AArch64/arm64-fp-imm-size.ll | 138 +++++++++++++-----
llvm/test/CodeGen/AArch64/arm64-fp-imm.ll | 63 +++++---
llvm/test/CodeGen/AArch64/arm64-vhadd.ll | 8 +-
llvm/test/CodeGen/AArch64/f16-instructions.ll | 8 +-
llvm/test/CodeGen/AArch64/fcvt-fixed.ll | 96 ++++++------
llvm/test/CodeGen/AArch64/fpow.ll | 34 +++--
.../AArch64/neon-compare-instructions.ll | 3 +-
llvm/test/CodeGen/AArch64/rem-by-const.ll | 23 +--
llvm/test/CodeGen/AArch64/select_const.ll | 119 ++++++++-------
llvm/test/CodeGen/AArch64/vecreduce-fadd.ll | 5 +-
15 files changed, 441 insertions(+), 217 deletions(-)
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 9ed05681de32d..75d7e264876a1 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -13091,7 +13091,7 @@ bool AArch64TargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT,
// however the mov+fmov sequence is always better because of the reduced
// cache pressure. The timings are still the same if you consider
// movw+movk+fmov vs. adrp+ldr (it's one instruction longer, but the
- // movw+movk is fused). So we limit up to 2 instrdduction at most.
+ // movw+movk is fused). So we limit up to 4 instructions at most.
SmallVector<AArch64_IMM::ImmInsnModel, 4> Insn;
AArch64_IMM::expandMOVImm(ImmInt.getZExtValue(), VT.getSizeInBits(), Insn);
assert(Insn.size() <= 4 &&
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64GlobalISelUtils.cpp b/llvm/lib/Target/AArch64/GISel/AArch64GlobalISelUtils.cpp
index d51466c623347..baf98ca8e4e3c 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64GlobalISelUtils.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64GlobalISelUtils.cpp
@@ -23,8 +23,8 @@ AArch64GISelUtils::getAArch64VectorSplat(const MachineInstr &MI,
if (MI.getOpcode() != AArch64::G_DUP)
return std::nullopt;
Register Src = MI.getOperand(1).getReg();
- if (auto ValAndVReg =
- getAnyConstantVRegValWithLookThrough(MI.getOperand(1).getReg(), MRI))
+ if (auto ValAndVReg = getAnyConstantVRegValWithLookThrough(
+ MI.getOperand(1).getReg(), MRI, true, true))
return RegOrConstant(ValAndVReg->Value.getSExtValue());
return RegOrConstant(Src);
}
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
index b05da9376d966..b922b7decb1b3 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
@@ -2348,7 +2348,8 @@ bool AArch64InstructionSelector::earlySelect(MachineInstr &I) {
// Before selecting a DUP instruction, check if it is better selected as a
// MOV or load from a constant pool.
Register Src = I.getOperand(1).getReg();
- auto ValAndVReg = getAnyConstantVRegValWithLookThrough(Src, MRI);
+ auto ValAndVReg =
+ getAnyConstantVRegValWithLookThrough(Src, MRI, true, true);
if (!ValAndVReg)
return false;
LLVMContext &Ctx = MF.getFunction().getContext();
@@ -5802,18 +5803,25 @@ bool AArch64InstructionSelector::tryOptConstantBuildVec(
// generate a constant pool load instead of a vector insert sequence.
SmallVector<Constant *, 16> Csts;
for (unsigned Idx = 1; Idx < I.getNumOperands(); ++Idx) {
- // Try to find G_CONSTANT or G_FCONSTANT
- auto *OpMI =
- getOpcodeDef(TargetOpcode::G_CONSTANT, I.getOperand(Idx).getReg(), MRI);
- if (OpMI)
- Csts.emplace_back(
- const_cast<ConstantInt *>(OpMI->getOperand(1).getCImm()));
- else if ((OpMI = getOpcodeDef(TargetOpcode::G_FCONSTANT,
- I.getOperand(Idx).getReg(), MRI)))
- Csts.emplace_back(
- const_cast<ConstantFP *>(OpMI->getOperand(1).getFPImm()));
- else
- return false;
+ Register OpReg = I.getOperand(Idx).getReg();
+ if (auto AnyConst =
+ getAnyConstantVRegValWithLookThrough(OpReg, MRI, true, true)) {
+ MachineInstr *DefMI = MRI.getVRegDef(AnyConst->VReg);
+
+ if (DefMI->getOpcode() == TargetOpcode::G_CONSTANT) {
+ Csts.emplace_back(
+ ConstantInt::get(MIB.getMF().getFunction().getContext(),
+ std::move(AnyConst->Value)));
+ continue;
+ }
+
+ if (DefMI->getOpcode() == TargetOpcode::G_FCONSTANT) {
+ Csts.emplace_back(
+ const_cast<ConstantFP *>(DefMI->getOperand(1).getFPImm()));
+ continue;
+ }
+ }
+ return false;
}
Constant *CV = ConstantVector::get(Csts);
if (!emitConstantVector(I.getOperand(0).getReg(), CV, MIB, MRI))
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
index f8b5739d1d13a..ceabe776f768b 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
@@ -30,6 +30,7 @@
#include "llvm/CodeGen/TargetOpcodes.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
+#include "llvm/IR/Constants.h"
#include "llvm/IR/IntrinsicsAArch64.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Threading.h"
@@ -358,12 +359,71 @@ AArch64RegisterBankInfo::getInstrAlternativeMappings(
return RegisterBankInfo::getInstrAlternativeMappings(MI);
}
+static bool isLegalFPImm(const MachineInstr &MI, const MachineRegisterInfo &MRI,
+ const AArch64Subtarget &STI) {
+ assert(MI.getOpcode() == TargetOpcode::G_FCONSTANT);
+ Register Dst = MI.getOperand(0).getReg();
+ LLT Ty = MRI.getType(Dst);
+ if (!Ty.isScalar())
+ return false;
+
+ unsigned Bits = Ty.getSizeInBits();
+ if (Bits != 16 && Bits != 32 && Bits != 64)
+ return false;
+
+ EVT VT = EVT::getFloatingPointVT(Bits);
+ bool OptForSize = MI.getMF()->getFunction().hasOptSize() ||
+ MI.getMF()->getFunction().hasMinSize();
+ const TargetLowering *TLI = STI.getTargetLowering();
+ return TLI->isFPImmLegal(MI.getOperand(1).getFPImm()->getValueAPF(), VT,
+ OptForSize);
+}
+
void AArch64RegisterBankInfo::applyMappingImpl(
MachineIRBuilder &Builder, const OperandsMapper &OpdMapper) const {
MachineInstr &MI = OpdMapper.getMI();
MachineRegisterInfo &MRI = OpdMapper.getMRI();
switch (MI.getOpcode()) {
+ case TargetOpcode::G_CONSTANT: {
+ Register Dst = MI.getOperand(0).getReg();
+ LLT DstTy = MRI.getType(Dst);
+ if (MRI.getRegBank(Dst) == &AArch64::GPRRegBank && DstTy.isScalar() &&
+ DstTy.getSizeInBits() < 32) {
+ Builder.setInsertPt(*MI.getParent(), std::next(MI.getIterator()));
+ Register ExtReg = MRI.createGenericVirtualRegister(LLT::scalar(32));
+ Builder.buildTrunc(Dst, ExtReg);
+
+ auto Val = MI.getOperand(1).getCImm()->getValue().zext(32);
+ LLVMContext &Ctx = Builder.getMF().getFunction().getContext();
+ MI.getOperand(1).setCImm(ConstantInt::get(Ctx, Val));
+ MI.getOperand(0).setReg(ExtReg);
+ MRI.setRegBank(ExtReg, AArch64::GPRRegBank);
+
+ for (MachineInstr &UseMI :
+ make_early_inc_range(MRI.use_nodbg_instructions(Dst))) {
+ if (UseMI.getOpcode() != AArch64::G_DUP)
+ continue;
+ for (MachineOperand &Op : UseMI.operands()) {
+ if (Op.isReg() && Op.getReg() == Dst)
+ Op.setReg(ExtReg);
+ }
+ }
+ }
+ return applyDefaultMapping(OpdMapper);
+ }
+ case TargetOpcode::G_FCONSTANT: {
+ Register Dst = MI.getOperand(0).getReg();
+ if (MRI.getRegBank(Dst) == &AArch64::GPRRegBank) {
+ const APFloat &Imm = MI.getOperand(1).getFPImm()->getValueAPF();
+ Builder.setInsertPt(*MI.getParent(), MI.getIterator());
+ Builder.buildConstant(Dst, Imm.bitcastToAPInt());
+ MI.eraseFromParent();
+ return;
+ }
+ return applyDefaultMapping(OpdMapper);
+ }
+
case TargetOpcode::G_STORE: {
Register Dst = MI.getOperand(0).getReg();
LLT Ty = MRI.getType(Dst);
@@ -855,6 +915,22 @@ AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
// Some of the floating-point instructions have mixed GPR and FPR operands:
// fine-tune the computed mapping.
switch (Opc) {
+ case TargetOpcode::G_CONSTANT: {
+ Register Dst = MI.getOperand(0).getReg();
+ LLT DstTy = MRI.getType(Dst);
+ if (DstTy.isScalar() && DstTy.getSizeInBits() < 32)
+ MappingID = CustomMappingID;
+ break;
+ }
+ case TargetOpcode::G_FCONSTANT: {
+ if (!isLegalFPImm(MI, MRI, STI) &&
+ MRI.getType(MI.getOperand(0).getReg()).getScalarSizeInBits() != 128) {
+ // Materialize in GPR and rely on later bank copies for FP uses.
+ MappingID = CustomMappingID;
+ OpRegBankIdx = {PMI_FirstGPR};
+ }
+ break;
+ }
case AArch64::G_DUP: {
Register ScalarReg = MI.getOperand(1).getReg();
LLT ScalarTy = MRI.getType(ScalarReg);
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/regbankselect-build-vector.mir b/llvm/test/CodeGen/AArch64/GlobalISel/regbankselect-build-vector.mir
index 015949ed8de95..55f316facfca3 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/regbankselect-build-vector.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/regbankselect-build-vector.mir
@@ -44,16 +44,41 @@ body: |
; They're all constant, so we can select it via a constant-pool load if needed
; and this form is more amenable to selection by patterns (without x-bank copies).
; CHECK-LABEL: name: g_constant_operands_on_gpr
- ; CHECK: [[C:%[0-9]+]]:gpr(s8) = G_CONSTANT i8 4
- ; CHECK-NEXT: [[C1:%[0-9]+]]:gpr(s8) = G_CONSTANT i8 10
- ; CHECK-NEXT: [[C2:%[0-9]+]]:gpr(s8) = G_CONSTANT i8 3
- ; CHECK-NEXT: [[C3:%[0-9]+]]:gpr(s8) = G_CONSTANT i8 11
- ; CHECK-NEXT: [[C4:%[0-9]+]]:gpr(s8) = G_CONSTANT i8 15
- ; CHECK-NEXT: [[C5:%[0-9]+]]:gpr(s8) = G_CONSTANT i8 44
- ; CHECK-NEXT: [[C6:%[0-9]+]]:gpr(s8) = G_CONSTANT i8 22
- ; CHECK-NEXT: [[C7:%[0-9]+]]:gpr(s8) = G_CONSTANT i8 19
- ; CHECK-NEXT: [[C8:%[0-9]+]]:gpr(s8) = G_CONSTANT i8 55
- ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:fpr(<16 x s8>) = G_BUILD_VECTOR [[C]](s8), [[C1]](s8), [[C2]](s8), [[C3]](s8), [[C4]](s8), [[C]](s8), [[C1]](s8), [[C5]](s8), [[C6]](s8), [[C4]](s8), [[C]](s8), [[C7]](s8), [[C2]](s8), [[C3]](s8), [[C4]](s8), [[C8]](s8)
+ ; CHECK: [[C:%[0-9]+]]:gpr(s32) = G_CONSTANT i32 4
+ ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:gpr(s8) = G_TRUNC [[C]](s32)
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:gpr(s32) = G_CONSTANT i32 10
+ ; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:gpr(s8) = G_TRUNC [[C1]](s32)
+ ; CHECK-NEXT: [[C2:%[0-9]+]]:gpr(s32) = G_CONSTANT i32 3
+ ; CHECK-NEXT: [[TRUNC2:%[0-9]+]]:gpr(s8) = G_TRUNC [[C2]](s32)
+ ; CHECK-NEXT: [[C3:%[0-9]+]]:gpr(s32) = G_CONSTANT i32 11
+ ; CHECK-NEXT: [[TRUNC3:%[0-9]+]]:gpr(s8) = G_TRUNC [[C3]](s32)
+ ; CHECK-NEXT: [[C4:%[0-9]+]]:gpr(s32) = G_CONSTANT i32 15
+ ; CHECK-NEXT: [[TRUNC4:%[0-9]+]]:gpr(s8) = G_TRUNC [[C4]](s32)
+ ; CHECK-NEXT: [[C5:%[0-9]+]]:gpr(s32) = G_CONSTANT i32 44
+ ; CHECK-NEXT: [[TRUNC5:%[0-9]+]]:gpr(s8) = G_TRUNC [[C5]](s32)
+ ; CHECK-NEXT: [[C6:%[0-9]+]]:gpr(s32) = G_CONSTANT i32 22
+ ; CHECK-NEXT: [[TRUNC6:%[0-9]+]]:gpr(s8) = G_TRUNC [[C6]](s32)
+ ; CHECK-NEXT: [[C7:%[0-9]+]]:gpr(s32) = G_CONSTANT i32 19
+ ; CHECK-NEXT: [[TRUNC7:%[0-9]+]]:gpr(s8) = G_TRUNC [[C7]](s32)
+ ; CHECK-NEXT: [[C8:%[0-9]+]]:gpr(s32) = G_CONSTANT i32 55
+ ; CHECK-NEXT: [[TRUNC8:%[0-9]+]]:gpr(s8) = G_TRUNC [[C8]](s32)
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr(s8) = COPY [[TRUNC]](s8)
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr(s8) = COPY [[TRUNC1]](s8)
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:fpr(s8) = COPY [[TRUNC2]](s8)
+ ; CHECK-NEXT: [[COPY3:%[0-9]+]]:fpr(s8) = COPY [[TRUNC3]](s8)
+ ; CHECK-NEXT: [[COPY4:%[0-9]+]]:fpr(s8) = COPY [[TRUNC4]](s8)
+ ; CHECK-NEXT: [[COPY5:%[0-9]+]]:fpr(s8) = COPY [[TRUNC]](s8)
+ ; CHECK-NEXT: [[COPY6:%[0-9]+]]:fpr(s8) = COPY [[TRUNC1]](s8)
+ ; CHECK-NEXT: [[COPY7:%[0-9]+]]:fpr(s8) = COPY [[TRUNC5]](s8)
+ ; CHECK-NEXT: [[COPY8:%[0-9]+]]:fpr(s8) = COPY [[TRUNC6]](s8)
+ ; CHECK-NEXT: [[COPY9:%[0-9]+]]:fpr(s8) = COPY [[TRUNC4]](s8)
+ ; CHECK-NEXT: [[COPY10:%[0-9]+]]:fpr(s8) = COPY [[TRUNC]](s8)
+ ; CHECK-NEXT: [[COPY11:%[0-9]+]]:fpr(s8) = COPY [[TRUNC7]](s8)
+ ; CHECK-NEXT: [[COPY12:%[0-9]+]]:fpr(s8) = COPY [[TRUNC2]](s8)
+ ; CHECK-NEXT: [[COPY13:%[0-9]+]]:fpr(s8) = COPY [[TRUNC3]](s8)
+ ; CHECK-NEXT: [[COPY14:%[0-9]+]]:fpr(s8) = COPY [[TRUNC4]](s8)
+ ; CHECK-NEXT: [[COPY15:%[0-9]+]]:fpr(s8) = COPY [[TRUNC8]](s8)
+ ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:fpr(<16 x s8>) = G_BUILD_VECTOR [[COPY]](s8), [[COPY1]](s8), [[COPY2]](s8), [[COPY3]](s8), [[COPY4]](s8), [[COPY5]](s8), [[COPY6]](s8), [[COPY7]](s8), [[COPY8]](s8), [[COPY9]](s8), [[COPY10]](s8), [[COPY11]](s8), [[COPY12]](s8), [[COPY13]](s8), [[COPY14]](s8), [[COPY15]](s8)
; CHECK-NEXT: $q0 = COPY [[BUILD_VECTOR]](<16 x s8>)
; CHECK-NEXT: RET_ReallyLR implicit $q0
%1:_(s8) = G_CONSTANT i8 4
diff --git a/llvm/test/CodeGen/AArch64/arm64-fp-imm-size.ll b/llvm/test/CodeGen/AArch64/arm64-fp-imm-size.ll
index cfb7c60f5a8b0..db219c926c0f2 100644
--- a/llvm/test/CodeGen/AArch64/arm64-fp-imm-size.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-fp-imm-size.ll
@@ -1,60 +1,126 @@
-; RUN: llc < %s -mtriple=arm64-apple-darwin | FileCheck %s
-; RUN: llc < %s -mtriple=arm64-apple-darwin -global-isel | FileCheck %s
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc < %s -mtriple=arm64-apple-darwin | FileCheck --check-prefixes=CHECK,CHECK-SD %s
+; RUN: llc < %s -mtriple=arm64-apple-darwin -global-isel | FileCheck --check-prefixes=CHECK,CHECK-GI %s
-; CHECK: literal8
-; CHECK: .quad 0x400921fb54442d18
define double @foo() optsize {
-; CHECK: _foo:
-; CHECK: adrp x[[REG:[0-9]+]], lCPI0_0 at PAGE
-; CHECK: ldr d0, [x[[REG]], lCPI0_0 at PAGEOFF]
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: foo:
+; CHECK-SD: ; %bb.0:
+; CHECK-SD-NEXT: Lloh0:
+; CHECK-SD-NEXT: adrp x8, lCPI0_0 at PAGE
+; CHECK-SD-NEXT: Lloh1:
+; CHECK-SD-NEXT: ldr d0, [x8, lCPI0_0 at PAGEOFF]
+; CHECK-SD-NEXT: ret
+; CHECK-SD-NEXT: .loh AdrpLdr Lloh0, Lloh1
+;
+; CHECK-GI-LABEL: foo:
+; CHECK-GI: ; %bb.0:
+; CHECK-GI-NEXT: mov x8, #11544 ; =0x2d18
+; CHECK-GI-NEXT: movk x8, #21572, lsl #16
+; CHECK-GI-NEXT: movk x8, #8699, lsl #32
+; CHECK-GI-NEXT: movk x8, #16393, lsl #48
+; CHECK-GI-NEXT: fmov d0, x8
+; CHECK-GI-NEXT: ret
ret double 0x400921FB54442D18
}
-; CHECK: literal8
-; CHECK: .quad 0x0000001fffffffc
define double @foo2() optsize {
-; CHECK: _foo2:
-; CHECK: adrp x[[REG:[0-9]+]], lCPI1_0 at PAGE
-; CHECK: ldr d0, [x[[REG]], lCPI1_0 at PAGEOFF]
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: foo2:
+; CHECK-SD: ; %bb.0:
+; CHECK-SD-NEXT: Lloh2:
+; CHECK-SD-NEXT: adrp x8, lCPI1_0 at PAGE
+; CHECK-SD-NEXT: Lloh3:
+; CHECK-SD-NEXT: ldr d0, [x8, lCPI1_0 at PAGEOFF]
+; CHECK-SD-NEXT: ret
+; CHECK-SD-NEXT: .loh AdrpLdr Lloh2, Lloh3
+;
+; CHECK-GI-LABEL: foo2:
+; CHECK-GI: ; %bb.0:
+; CHECK-GI-NEXT: mov x8, #137438887936 ; =0x1fffff0000
+; CHECK-GI-NEXT: movk x8, #65473
+; CHECK-GI-NEXT: fmov d0, x8
+; CHECK-GI-NEXT: ret
ret double 0x1FFFFFFFC1
}
define float @bar() optsize {
-; CHECK: _bar:
-; CHECK: adrp x[[REG:[0-9]+]], lCPI2_0 at PAGE
-; CHECK: ldr s0, [x[[REG]], lCPI2_0 at PAGEOFF]
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: bar:
+; CHECK-SD: ; %bb.0:
+; CHECK-SD-NEXT: Lloh4:
+; CHECK-SD-NEXT: adrp x8, lCPI2_0 at PAGE
+; CHECK-SD-NEXT: Lloh5:
+; CHECK-SD-NEXT: ldr s0, [x8, lCPI2_0 at PAGEOFF]
+; CHECK-SD-NEXT: ret
+; CHECK-SD-NEXT: .loh AdrpLdr Lloh4, Lloh5
+;
+; CHECK-GI-LABEL: bar:
+; CHECK-GI: ; %bb.0:
+; CHECK-GI-NEXT: mov w8, #4059 ; =0xfdb
+; CHECK-GI-NEXT: movk w8, #16457, lsl #16
+; CHECK-GI-NEXT: fmov s0, w8
+; CHECK-GI-NEXT: ret
ret float 0x400921FB60000000
}
-; CHECK: literal16
-; CHECK: .quad 0
-; CHECK: .quad 0
define fp128 @baz() optsize {
-; CHECK: _baz:
-; CHECK: adrp x[[REG:[0-9]+]], lCPI3_0 at PAGE
-; CHECK: ldr q0, [x[[REG]], lCPI3_0 at PAGEOFF]
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: baz:
+; CHECK-SD: ; %bb.0:
+; CHECK-SD-NEXT: Lloh6:
+; CHECK-SD-NEXT: adrp x8, lCPI3_0 at PAGE
+; CHECK-SD-NEXT: Lloh7:
+; CHECK-SD-NEXT: ldr q0, [x8, lCPI3_0 at PAGEOFF]
+; CHECK-SD-NEXT: ret
+; CHECK-SD-NEXT: .loh AdrpLdr Lloh6, Lloh7
+;
+; CHECK-GI-LABEL: baz:
+; CHECK-GI: ; %bb.0:
+; CHECK-GI-NEXT: Lloh0:
+; CHECK-GI-NEXT: adrp x8, lCPI3_0 at PAGE
+; CHECK-GI-NEXT: Lloh1:
+; CHECK-GI-NEXT: ldr q0, [x8, lCPI3_0 at PAGEOFF]
+; CHECK-GI-NEXT: ret
+; CHECK-GI-NEXT: .loh AdrpLdr Lloh0, Lloh1
ret fp128 0xL00000000000000000000000000000000
}
-; CHECK: literal8
-; CHECK: .quad 0x0000001fffffffd
define double @foo2_pgso() !prof !14 {
-; CHECK: _foo2_pgso:
-; CHECK: adrp x[[REG:[0-9]+]], lCPI4_0 at PAGE
-; CHECK: ldr d0, [x[[REG]], lCPI4_0 at PAGEOFF]
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: foo2_pgso:
+; CHECK-SD: ; %bb.0:
+; CHECK-SD-NEXT: Lloh8:
+; CHECK-SD-NEXT: adrp x8, lCPI4_0 at PAGE
+; CHECK-SD-NEXT: Lloh9:
+; CHECK-SD-NEXT: ldr d0, [x8, lCPI4_0 at PAGEOFF]
+; CHECK-SD-NEXT: ret
+; CHECK-SD-NEXT: .loh AdrpLdr Lloh8, Lloh9
+;
+; CHECK-GI-LABEL: foo2_pgso:
+; CHECK-GI: ; %bb.0:
+; CHECK-GI-NEXT: Lloh2:
+; CHECK-GI-NEXT: adrp x8, lCPI4_0 at PAGE
+; CHECK-GI-NEXT: Lloh3:
+; CHECK-GI-NEXT: ldr d0, [x8, lCPI4_0 at PAGEOFF]
+; CHECK-GI-NEXT: ret
+; CHECK-GI-NEXT: .loh AdrpLdr Lloh2, Lloh3
ret double 0x1FFFFFFFd1
}
define float @bar_pgso() !prof !14 {
-; CHECK: _bar_pgso:
-; CHECK: adrp x[[REG:[0-9]+]], lCPI5_0 at PAGE
-; CHECK: ldr s0, [x[[REG]], lCPI5_0 at PAGEOFF]
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: bar_pgso:
+; CHECK-SD: ; %bb.0:
+; CHECK-SD-NEXT: Lloh10:
+; CHECK-SD-NEXT: adrp x8, lCPI5_0 at PAGE
+; CHECK-SD-NEXT: Lloh11:
+; CHECK-SD-NEXT: ldr s0, [x8, lCPI5_0 at PAGEOFF]
+; CHECK-SD-NEXT: ret
+; CHECK-SD-NEXT: .loh AdrpLdr Lloh10, Lloh11
+;
+; CHECK-GI-LABEL: bar_pgso:
+; CHECK-GI: ; %bb.0:
+; CHECK-GI-NEXT: Lloh4:
+; CHECK-GI-NEXT: adrp x8, lCPI5_0 at PAGE
+; CHECK-GI-NEXT: Lloh5:
+; CHECK-GI-NEXT: ldr s0, [x8, lCPI5_0 at PAGEOFF]
+; CHECK-GI-NEXT: ret
+; CHECK-GI-NEXT: .loh AdrpLdr Lloh4, Lloh5
ret float 0x400921FB80000000
}
@@ -74,3 +140,5 @@ define float @bar_pgso() !prof !14 {
!12 = !{i32 999000, i64 100, i32 1}
!13 = !{i32 999999, i64 1, i32 2}
!14 = !{!"function_entry_count", i64 0}
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; CHECK: {{.*}}
diff --git a/llvm/test/CodeGen/AArch64/arm64-fp-imm.ll b/llvm/test/CodeGen/AArch64/arm64-fp-imm.ll
index 61eb67486ae3d..f541715235e03 100644
--- a/llvm/test/CodeGen/AArch64/arm64-fp-imm.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-fp-imm.ll
@@ -1,32 +1,55 @@
-; RUN: llc < %s -mtriple=arm64-apple-darwin | FileCheck %s
-; RUN: llc < %s -mtriple=arm64-apple-darwin -global-isel | FileCheck %s
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc < %s -mtriple=arm64-apple-darwin | FileCheck --check-prefixes=CHECK,CHECK-SD %s
+; RUN: llc < %s -mtriple=arm64-apple-darwin -global-isel | FileCheck --check-prefixes=CHECK,CHECK-GI %s
-; CHECK: literal8
-; CHECK: .quad 0x400921fb54442d18
define double @foo() {
-; CHECK: _foo:
-; CHECK: adrp x[[REG:[0-9]+]], lCPI0_0 at PAGE
-; CHECK: ldr d0, [x[[REG]], lCPI0_0 at PAGEOFF]
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: foo:
+; CHECK-SD: ; %bb.0:
+; CHECK-SD-NEXT: Lloh0:
+; CHECK-SD-NEXT: adrp x8, lCPI0_0 at PAGE
+; CHECK-SD-NEXT: Lloh1:
+; CHECK-SD-NEXT: ldr d0, [x8, lCPI0_0 at PAGEOFF]
+; CHECK-SD-NEXT: ret
+; CHECK-SD-NEXT: .loh AdrpLdr Lloh0, Lloh1
+;
+; CHECK-GI-LABEL: foo:
+; CHECK-GI: ; %bb.0:
+; CHECK-GI-NEXT: mov x8, #11544 ; =0x2d18
+; CHECK-GI-NEXT: movk x8, #21572, lsl #16
+; CHECK-GI-NEXT: movk x8, #8699, lsl #32
+; CHECK-GI-NEXT: movk x8, #16393, lsl #48
+; CHECK-GI-NEXT: fmov d0, x8
+; CHECK-GI-NEXT: ret
ret double 0x400921FB54442D18
}
define float @bar() {
-; CHECK: _bar:
-; CHECK: mov [[REG:w[0-9]+]], #4059
-; CHECK: movk [[REG]], #16457, lsl #16
-; CHECK: fmov s0, [[REG]]
-; CHECK-NEXT: ret
+; CHECK-LABEL: bar:
+; CHECK: ; %bb.0:
+; CHECK-NEXT: mov w8, #4059 ; =0xfdb
+; CHECK-NEXT: movk w8, #16457, lsl #16
+; CHECK-NEXT: fmov s0, w8
+; CHECK-NEXT: ret
ret float 0x400921FB60000000
}
-; CHECK: literal16
-; CHECK: .quad 0
-; CHECK: .quad 0
define fp128 @baz() {
-; CHECK: _baz:
-; CHECK: adrp x[[REG:[0-9]+]], lCPI2_0 at PAGE
-; CHECK: ldr q0, [x[[REG]], lCPI2_0 at PAGEOFF]
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: baz:
+; CHECK-SD: ; %bb.0:
+; CHECK-SD-NEXT: Lloh2:
+; CHECK-SD-NEXT: adrp x8, lCPI2_0 at PAGE
+; CHECK-SD-NEXT: Lloh3:
+; CHECK-SD-NEXT: ldr q0, [x8, lCPI2_0 at PAGEOFF]
+; CHECK-SD-NEXT: ret
+; CHECK-SD-NEXT: .loh AdrpLdr Lloh2, Lloh3
+;
+; CHECK-GI-LABEL: baz:
+; CHECK-GI: ; %bb.0:
+; CHECK-GI-NEXT: Lloh0:
+; CHECK-GI-NEXT: adrp x8, lCPI2_0 at PAGE
+; CHECK-GI-NEXT: Lloh1:
+; CHECK-GI-NEXT: ldr q0, [x8, lCPI2_0 at PAGEOFF]
+; CHECK-GI-NEXT: ret
+; CHECK-GI-NEXT: .loh AdrpLdr Lloh0, Lloh1
ret fp128 0xL00000000000000000000000000000000
}
diff --git a/llvm/test/CodeGen/AArch64/arm64-vhadd.ll b/llvm/test/CodeGen/AArch64/arm64-vhadd.ll
index 09ea9eeb03914..4723867bc99f0 100644
--- a/llvm/test/CodeGen/AArch64/arm64-vhadd.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-vhadd.ll
@@ -1437,7 +1437,7 @@ define <2 x i16> @rhadd8x2_sext_asr(<2 x i8> %src1, <2 x i8> %src2) {
; CHECK-GI-NEXT: shl.2s v1, v1, #24
; CHECK-GI-NEXT: shl.2s v0, v0, #24
; CHECK-GI-NEXT: mov w8, #1 // =0x1
-; CHECK-GI-NEXT: dup.2s v2, w8
+; CHECK-GI-NEXT: movi.2s v2, #1
; CHECK-GI-NEXT: sshr.2s v1, v1, #24
; CHECK-GI-NEXT: ssra.2s v1, v0, #24
; CHECK-GI-NEXT: fmov s0, w8
@@ -1472,7 +1472,7 @@ define <2 x i16> @rhadd8x2_zext_asr(<2 x i8> %src1, <2 x i8> %src2) {
; CHECK-GI-NEXT: mov w8, #1 // =0x1
; CHECK-GI-NEXT: and.8b v0, v0, v2
; CHECK-GI-NEXT: and.8b v1, v1, v2
-; CHECK-GI-NEXT: dup.2s v2, w8
+; CHECK-GI-NEXT: movi.2s v2, #1
; CHECK-GI-NEXT: add.2s v0, v0, v1
; CHECK-GI-NEXT: fmov s1, w8
; CHECK-GI-NEXT: add.2s v0, v0, v2
@@ -1510,7 +1510,7 @@ define <2 x i16> @rhadd8x2_sext_lsr(<2 x i8> %src1, <2 x i8> %src2) {
; CHECK-GI-NEXT: shl.2s v1, v1, #24
; CHECK-GI-NEXT: shl.2s v0, v0, #24
; CHECK-GI-NEXT: mov w8, #1 // =0x1
-; CHECK-GI-NEXT: dup.2s v2, w8
+; CHECK-GI-NEXT: movi.2s v2, #1
; CHECK-GI-NEXT: sshr.2s v1, v1, #24
; CHECK-GI-NEXT: ssra.2s v1, v0, #24
; CHECK-GI-NEXT: fmov s0, w8
@@ -1545,7 +1545,7 @@ define <2 x i16> @rhadd8x2_zext_lsr(<2 x i8> %src1, <2 x i8> %src2) {
; CHECK-GI-NEXT: mov w8, #1 // =0x1
; CHECK-GI-NEXT: and.8b v0, v0, v2
; CHECK-GI-NEXT: and.8b v1, v1, v2
-; CHECK-GI-NEXT: dup.2s v2, w8
+; CHECK-GI-NEXT: movi.2s v2, #1
; CHECK-GI-NEXT: add.2s v0, v0, v1
; CHECK-GI-NEXT: fmov s1, w8
; CHECK-GI-NEXT: add.2s v0, v0, v2
diff --git a/llvm/test/CodeGen/AArch64/f16-instructions.ll b/llvm/test/CodeGen/AArch64/f16-instructions.ll
index f6d701b518699..7101d38c47766 100644
--- a/llvm/test/CodeGen/AArch64/f16-instructions.ll
+++ b/llvm/test/CodeGen/AArch64/f16-instructions.ll
@@ -785,14 +785,12 @@ define void @test_fccmp(half %in, ptr %out) {
; CHECK-CVT-GI-NEXT: // kill: def $h0 killed $h0 def $s0
; CHECK-CVT-GI-NEXT: fcvt s1, h0
; CHECK-CVT-GI-NEXT: fmov s2, #5.00000000
-; CHECK-CVT-GI-NEXT: adrp x8, .LCPI29_0
+; CHECK-CVT-GI-NEXT: mov w8, #17664 // =0x4500
; CHECK-CVT-GI-NEXT: fmov s3, #8.00000000
+; CHECK-CVT-GI-NEXT: fmov w9, s0
; CHECK-CVT-GI-NEXT: fcmp s1, s2
-; CHECK-CVT-GI-NEXT: ldr h2, [x8, :lo12:.LCPI29_0]
-; CHECK-CVT-GI-NEXT: fmov w8, s0
-; CHECK-CVT-GI-NEXT: fmov w9, s2
; CHECK-CVT-GI-NEXT: fccmp s1, s3, #4, mi
-; CHECK-CVT-GI-NEXT: csel w8, w8, w9, gt
+; CHECK-CVT-GI-NEXT: csel w8, w9, w8, gt
; CHECK-CVT-GI-NEXT: strh w8, [x0]
; CHECK-CVT-GI-NEXT: ret
;
diff --git a/llvm/test/CodeGen/AArch64/fcvt-fixed.ll b/llvm/test/CodeGen/AArch64/fcvt-fixed.ll
index 743d1604388de..22e2694063330 100644
--- a/llvm/test/CodeGen/AArch64/fcvt-fixed.ll
+++ b/llvm/test/CodeGen/AArch64/fcvt-fixed.ll
@@ -166,8 +166,8 @@ define i32 @fcvtzs_f16_i32_7(half %flt) {
;
; CHECK-GI-FP16-LABEL: fcvtzs_f16_i32_7:
; CHECK-GI-FP16: // %bb.0:
-; CHECK-GI-FP16-NEXT: adrp x8, .LCPI8_0
-; CHECK-GI-FP16-NEXT: ldr h1, [x8, :lo12:.LCPI8_0]
+; CHECK-GI-FP16-NEXT: mov w8, #22528 // =0x5800
+; CHECK-GI-FP16-NEXT: fmov s1, w8
; CHECK-GI-FP16-NEXT: fmul h0, h0, h1
; CHECK-GI-FP16-NEXT: fcvtzs w0, h0
; CHECK-GI-FP16-NEXT: ret
@@ -194,8 +194,8 @@ define i32 @fcvtzs_f16_i32_15(half %flt) {
;
; CHECK-GI-FP16-LABEL: fcvtzs_f16_i32_15:
; CHECK-GI-FP16: // %bb.0:
-; CHECK-GI-FP16-NEXT: adrp x8, .LCPI9_0
-; CHECK-GI-FP16-NEXT: ldr h1, [x8, :lo12:.LCPI9_0]
+; CHECK-GI-FP16-NEXT: mov w8, #30720 // =0x7800
+; CHECK-GI-FP16-NEXT: fmov s1, w8
; CHECK-GI-FP16-NEXT: fmul h0, h0, h1
; CHECK-GI-FP16-NEXT: fcvtzs w0, h0
; CHECK-GI-FP16-NEXT: ret
@@ -222,8 +222,8 @@ define i64 @fcvtzs_f16_i64_7(half %flt) {
;
; CHECK-GI-FP16-LABEL: fcvtzs_f16_i64_7:
; CHECK-GI-FP16: // %bb.0:
-; CHECK-GI-FP16-NEXT: adrp x8, .LCPI10_0
-; CHECK-GI-FP16-NEXT: ldr h1, [x8, :lo12:.LCPI10_0]
+; CHECK-GI-FP16-NEXT: mov w8, #22528 // =0x5800
+; CHECK-GI-FP16-NEXT: fmov s1, w8
; CHECK-GI-FP16-NEXT: fmul h0, h0, h1
; CHECK-GI-FP16-NEXT: fcvtzs x0, h0
; CHECK-GI-FP16-NEXT: ret
@@ -250,8 +250,8 @@ define i64 @fcvtzs_f16_i64_15(half %flt) {
;
; CHECK-GI-FP16-LABEL: fcvtzs_f16_i64_15:
; CHECK-GI-FP16: // %bb.0:
-; CHECK-GI-FP16-NEXT: adrp x8, .LCPI11_0
-; CHECK-GI-FP16-NEXT: ldr h1, [x8, :lo12:.LCPI11_0]
+; CHECK-GI-FP16-NEXT: mov w8, #30720 // =0x7800
+; CHECK-GI-FP16-NEXT: fmov s1, w8
; CHECK-GI-FP16-NEXT: fmul h0, h0, h1
; CHECK-GI-FP16-NEXT: fcvtzs x0, h0
; CHECK-GI-FP16-NEXT: ret
@@ -422,8 +422,8 @@ define i32 @fcvtzu_f16_i32_7(half %flt) {
;
; CHECK-GI-FP16-LABEL: fcvtzu_f16_i32_7:
; CHECK-GI-FP16: // %bb.0:
-; CHECK-GI-FP16-NEXT: adrp x8, .LCPI20_0
-; CHECK-GI-FP16-NEXT: ldr h1, [x8, :lo12:.LCPI20_0]
+; CHECK-GI-FP16-NEXT: mov w8, #22528 // =0x5800
+; CHECK-GI-FP16-NEXT: fmov s1, w8
; CHECK-GI-FP16-NEXT: fmul h0, h0, h1
; CHECK-GI-FP16-NEXT: fcvtzu w0, h0
; CHECK-GI-FP16-NEXT: ret
@@ -450,8 +450,8 @@ define i32 @fcvtzu_f16_i32_15(half %flt) {
;
; CHECK-GI-FP16-LABEL: fcvtzu_f16_i32_15:
; CHECK-GI-FP16: // %bb.0:
-; CHECK-GI-FP16-NEXT: adrp x8, .LCPI21_0
-; CHECK-GI-FP16-NEXT: ldr h1, [x8, :lo12:.LCPI21_0]
+; CHECK-GI-FP16-NEXT: mov w8, #30720 // =0x7800
+; CHECK-GI-FP16-NEXT: fmov s1, w8
; CHECK-GI-FP16-NEXT: fmul h0, h0, h1
; CHECK-GI-FP16-NEXT: fcvtzu w0, h0
; CHECK-GI-FP16-NEXT: ret
@@ -478,8 +478,8 @@ define i64 @fcvtzu_f16_i64_7(half %flt) {
;
; CHECK-GI-FP16-LABEL: fcvtzu_f16_i64_7:
; CHECK-GI-FP16: // %bb.0:
-; CHECK-GI-FP16-NEXT: adrp x8, .LCPI22_0
-; CHECK-GI-FP16-NEXT: ldr h1, [x8, :lo12:.LCPI22_0]
+; CHECK-GI-FP16-NEXT: mov w8, #22528 // =0x5800
+; CHECK-GI-FP16-NEXT: fmov s1, w8
; CHECK-GI-FP16-NEXT: fmul h0, h0, h1
; CHECK-GI-FP16-NEXT: fcvtzu x0, h0
; CHECK-GI-FP16-NEXT: ret
@@ -506,8 +506,8 @@ define i64 @fcvtzu_f16_i64_15(half %flt) {
;
; CHECK-GI-FP16-LABEL: fcvtzu_f16_i64_15:
; CHECK-GI-FP16: // %bb.0:
-; CHECK-GI-FP16-NEXT: adrp x8, .LCPI23_0
-; CHECK-GI-FP16-NEXT: ldr h1, [x8, :lo12:.LCPI23_0]
+; CHECK-GI-FP16-NEXT: mov w8, #30720 // =0x7800
+; CHECK-GI-FP16-NEXT: fmov s1, w8
; CHECK-GI-FP16-NEXT: fmul h0, h0, h1
; CHECK-GI-FP16-NEXT: fcvtzu x0, h0
; CHECK-GI-FP16-NEXT: ret
@@ -689,8 +689,8 @@ define half @scvtf_f16_i32_7(i32 %int) {
; CHECK-GI-FP16-LABEL: scvtf_f16_i32_7:
; CHECK-GI-FP16: // %bb.0:
; CHECK-GI-FP16-NEXT: scvtf h0, w0
-; CHECK-GI-FP16-NEXT: adrp x8, .LCPI32_0
-; CHECK-GI-FP16-NEXT: ldr h1, [x8, :lo12:.LCPI32_0]
+; CHECK-GI-FP16-NEXT: mov w8, #22528 // =0x5800
+; CHECK-GI-FP16-NEXT: fmov s1, w8
; CHECK-GI-FP16-NEXT: fdiv h0, h0, h1
; CHECK-GI-FP16-NEXT: ret
%cvt = sitofp i32 %int to half
@@ -727,8 +727,8 @@ define half @scvtf_f16_i32_15(i32 %int) {
; CHECK-GI-FP16-LABEL: scvtf_f16_i32_15:
; CHECK-GI-FP16: // %bb.0:
; CHECK-GI-FP16-NEXT: scvtf h0, w0
-; CHECK-GI-FP16-NEXT: adrp x8, .LCPI33_0
-; CHECK-GI-FP16-NEXT: ldr h1, [x8, :lo12:.LCPI33_0]
+; CHECK-GI-FP16-NEXT: mov w8, #30720 // =0x7800
+; CHECK-GI-FP16-NEXT: fmov s1, w8
; CHECK-GI-FP16-NEXT: fdiv h0, h0, h1
; CHECK-GI-FP16-NEXT: ret
%cvt = sitofp i32 %int to half
@@ -765,8 +765,8 @@ define half @scvtf_f16_i64_7(i64 %long) {
; CHECK-GI-FP16-LABEL: scvtf_f16_i64_7:
; CHECK-GI-FP16: // %bb.0:
; CHECK-GI-FP16-NEXT: scvtf h0, x0
-; CHECK-GI-FP16-NEXT: adrp x8, .LCPI34_0
-; CHECK-GI-FP16-NEXT: ldr h1, [x8, :lo12:.LCPI34_0]
+; CHECK-GI-FP16-NEXT: mov w8, #22528 // =0x5800
+; CHECK-GI-FP16-NEXT: fmov s1, w8
; CHECK-GI-FP16-NEXT: fdiv h0, h0, h1
; CHECK-GI-FP16-NEXT: ret
%cvt = sitofp i64 %long to half
@@ -803,8 +803,8 @@ define half @scvtf_f16_i64_15(i64 %long) {
; CHECK-GI-FP16-LABEL: scvtf_f16_i64_15:
; CHECK-GI-FP16: // %bb.0:
; CHECK-GI-FP16-NEXT: scvtf h0, x0
-; CHECK-GI-FP16-NEXT: adrp x8, .LCPI35_0
-; CHECK-GI-FP16-NEXT: ldr h1, [x8, :lo12:.LCPI35_0]
+; CHECK-GI-FP16-NEXT: mov w8, #30720 // =0x7800
+; CHECK-GI-FP16-NEXT: fmov s1, w8
; CHECK-GI-FP16-NEXT: fdiv h0, h0, h1
; CHECK-GI-FP16-NEXT: ret
%cvt = sitofp i64 %long to half
@@ -985,8 +985,8 @@ define half @ucvtf_f16_i32_7(i32 %int) {
; CHECK-GI-FP16-LABEL: ucvtf_f16_i32_7:
; CHECK-GI-FP16: // %bb.0:
; CHECK-GI-FP16-NEXT: ucvtf h0, w0
-; CHECK-GI-FP16-NEXT: adrp x8, .LCPI44_0
-; CHECK-GI-FP16-NEXT: ldr h1, [x8, :lo12:.LCPI44_0]
+; CHECK-GI-FP16-NEXT: mov w8, #22528 // =0x5800
+; CHECK-GI-FP16-NEXT: fmov s1, w8
; CHECK-GI-FP16-NEXT: fdiv h0, h0, h1
; CHECK-GI-FP16-NEXT: ret
%cvt = uitofp i32 %int to half
@@ -1023,8 +1023,8 @@ define half @ucvtf_f16_i32_15(i32 %int) {
; CHECK-GI-FP16-LABEL: ucvtf_f16_i32_15:
; CHECK-GI-FP16: // %bb.0:
; CHECK-GI-FP16-NEXT: ucvtf h0, w0
-; CHECK-GI-FP16-NEXT: adrp x8, .LCPI45_0
-; CHECK-GI-FP16-NEXT: ldr h1, [x8, :lo12:.LCPI45_0]
+; CHECK-GI-FP16-NEXT: mov w8, #30720 // =0x7800
+; CHECK-GI-FP16-NEXT: fmov s1, w8
; CHECK-GI-FP16-NEXT: fdiv h0, h0, h1
; CHECK-GI-FP16-NEXT: ret
%cvt = uitofp i32 %int to half
@@ -1061,8 +1061,8 @@ define half @ucvtf_f16_i64_7(i64 %long) {
; CHECK-GI-FP16-LABEL: ucvtf_f16_i64_7:
; CHECK-GI-FP16: // %bb.0:
; CHECK-GI-FP16-NEXT: ucvtf h0, x0
-; CHECK-GI-FP16-NEXT: adrp x8, .LCPI46_0
-; CHECK-GI-FP16-NEXT: ldr h1, [x8, :lo12:.LCPI46_0]
+; CHECK-GI-FP16-NEXT: mov w8, #22528 // =0x5800
+; CHECK-GI-FP16-NEXT: fmov s1, w8
; CHECK-GI-FP16-NEXT: fdiv h0, h0, h1
; CHECK-GI-FP16-NEXT: ret
%cvt = uitofp i64 %long to half
@@ -1099,8 +1099,8 @@ define half @ucvtf_f16_i64_15(i64 %long) {
; CHECK-GI-FP16-LABEL: ucvtf_f16_i64_15:
; CHECK-GI-FP16: // %bb.0:
; CHECK-GI-FP16-NEXT: ucvtf h0, x0
-; CHECK-GI-FP16-NEXT: adrp x8, .LCPI47_0
-; CHECK-GI-FP16-NEXT: ldr h1, [x8, :lo12:.LCPI47_0]
+; CHECK-GI-FP16-NEXT: mov w8, #30720 // =0x7800
+; CHECK-GI-FP16-NEXT: fmov s1, w8
; CHECK-GI-FP16-NEXT: fdiv h0, h0, h1
; CHECK-GI-FP16-NEXT: ret
%cvt = uitofp i64 %long to half
@@ -1261,8 +1261,8 @@ define i32 @fcvtzs_sat_f16_i32_7(half %dbl) {
;
; CHECK-GI-FP16-LABEL: fcvtzs_sat_f16_i32_7:
; CHECK-GI-FP16: // %bb.0:
-; CHECK-GI-FP16-NEXT: adrp x8, .LCPI55_0
-; CHECK-GI-FP16-NEXT: ldr h1, [x8, :lo12:.LCPI55_0]
+; CHECK-GI-FP16-NEXT: mov w8, #22528 // =0x5800
+; CHECK-GI-FP16-NEXT: fmov s1, w8
; CHECK-GI-FP16-NEXT: fmul h0, h0, h1
; CHECK-GI-FP16-NEXT: fcvtzs w0, h0
; CHECK-GI-FP16-NEXT: ret
@@ -1289,8 +1289,8 @@ define i32 @fcvtzs_sat_f16_i32_15(half %dbl) {
;
; CHECK-GI-FP16-LABEL: fcvtzs_sat_f16_i32_15:
; CHECK-GI-FP16: // %bb.0:
-; CHECK-GI-FP16-NEXT: adrp x8, .LCPI56_0
-; CHECK-GI-FP16-NEXT: ldr h1, [x8, :lo12:.LCPI56_0]
+; CHECK-GI-FP16-NEXT: mov w8, #30720 // =0x7800
+; CHECK-GI-FP16-NEXT: fmov s1, w8
; CHECK-GI-FP16-NEXT: fmul h0, h0, h1
; CHECK-GI-FP16-NEXT: fcvtzs w0, h0
; CHECK-GI-FP16-NEXT: ret
@@ -1317,8 +1317,8 @@ define i64 @fcvtzs_sat_f16_i64_7(half %dbl) {
;
; CHECK-GI-FP16-LABEL: fcvtzs_sat_f16_i64_7:
; CHECK-GI-FP16: // %bb.0:
-; CHECK-GI-FP16-NEXT: adrp x8, .LCPI57_0
-; CHECK-GI-FP16-NEXT: ldr h1, [x8, :lo12:.LCPI57_0]
+; CHECK-GI-FP16-NEXT: mov w8, #22528 // =0x5800
+; CHECK-GI-FP16-NEXT: fmov s1, w8
; CHECK-GI-FP16-NEXT: fmul h0, h0, h1
; CHECK-GI-FP16-NEXT: fcvtzs x0, h0
; CHECK-GI-FP16-NEXT: ret
@@ -1345,8 +1345,8 @@ define i64 @fcvtzs_sat_f16_i64_15(half %dbl) {
;
; CHECK-GI-FP16-LABEL: fcvtzs_sat_f16_i64_15:
; CHECK-GI-FP16: // %bb.0:
-; CHECK-GI-FP16-NEXT: adrp x8, .LCPI58_0
-; CHECK-GI-FP16-NEXT: ldr h1, [x8, :lo12:.LCPI58_0]
+; CHECK-GI-FP16-NEXT: mov w8, #30720 // =0x7800
+; CHECK-GI-FP16-NEXT: fmov s1, w8
; CHECK-GI-FP16-NEXT: fmul h0, h0, h1
; CHECK-GI-FP16-NEXT: fcvtzs x0, h0
; CHECK-GI-FP16-NEXT: ret
@@ -1507,8 +1507,8 @@ define i32 @fcvtzu_sat_f16_i32_7(half %dbl) {
;
; CHECK-GI-FP16-LABEL: fcvtzu_sat_f16_i32_7:
; CHECK-GI-FP16: // %bb.0:
-; CHECK-GI-FP16-NEXT: adrp x8, .LCPI66_0
-; CHECK-GI-FP16-NEXT: ldr h1, [x8, :lo12:.LCPI66_0]
+; CHECK-GI-FP16-NEXT: mov w8, #22528 // =0x5800
+; CHECK-GI-FP16-NEXT: fmov s1, w8
; CHECK-GI-FP16-NEXT: fmul h0, h0, h1
; CHECK-GI-FP16-NEXT: fcvtzu w0, h0
; CHECK-GI-FP16-NEXT: ret
@@ -1535,8 +1535,8 @@ define i32 @fcvtzu_sat_f16_i32_15(half %dbl) {
;
; CHECK-GI-FP16-LABEL: fcvtzu_sat_f16_i32_15:
; CHECK-GI-FP16: // %bb.0:
-; CHECK-GI-FP16-NEXT: adrp x8, .LCPI67_0
-; CHECK-GI-FP16-NEXT: ldr h1, [x8, :lo12:.LCPI67_0]
+; CHECK-GI-FP16-NEXT: mov w8, #30720 // =0x7800
+; CHECK-GI-FP16-NEXT: fmov s1, w8
; CHECK-GI-FP16-NEXT: fmul h0, h0, h1
; CHECK-GI-FP16-NEXT: fcvtzu w0, h0
; CHECK-GI-FP16-NEXT: ret
@@ -1563,8 +1563,8 @@ define i64 @fcvtzu_sat_f16_i64_7(half %dbl) {
;
; CHECK-GI-FP16-LABEL: fcvtzu_sat_f16_i64_7:
; CHECK-GI-FP16: // %bb.0:
-; CHECK-GI-FP16-NEXT: adrp x8, .LCPI68_0
-; CHECK-GI-FP16-NEXT: ldr h1, [x8, :lo12:.LCPI68_0]
+; CHECK-GI-FP16-NEXT: mov w8, #22528 // =0x5800
+; CHECK-GI-FP16-NEXT: fmov s1, w8
; CHECK-GI-FP16-NEXT: fmul h0, h0, h1
; CHECK-GI-FP16-NEXT: fcvtzu x0, h0
; CHECK-GI-FP16-NEXT: ret
@@ -1591,8 +1591,8 @@ define i64 @fcvtzu_sat_f16_i64_15(half %dbl) {
;
; CHECK-GI-FP16-LABEL: fcvtzu_sat_f16_i64_15:
; CHECK-GI-FP16: // %bb.0:
-; CHECK-GI-FP16-NEXT: adrp x8, .LCPI69_0
-; CHECK-GI-FP16-NEXT: ldr h1, [x8, :lo12:.LCPI69_0]
+; CHECK-GI-FP16-NEXT: mov w8, #30720 // =0x7800
+; CHECK-GI-FP16-NEXT: fmov s1, w8
; CHECK-GI-FP16-NEXT: fmul h0, h0, h1
; CHECK-GI-FP16-NEXT: fcvtzu x0, h0
; CHECK-GI-FP16-NEXT: ret
diff --git a/llvm/test/CodeGen/AArch64/fpow.ll b/llvm/test/CodeGen/AArch64/fpow.ll
index 3e9e1da87cd75..005352ab3486b 100644
--- a/llvm/test/CodeGen/AArch64/fpow.ll
+++ b/llvm/test/CodeGen/AArch64/fpow.ll
@@ -47,16 +47,30 @@ entry:
}
define <1 x double> @pow_v1f64(<1 x double> %x) {
-; CHECK-LABEL: pow_v1f64:
-; CHECK: // %bb.0:
-; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
-; CHECK-NEXT: .cfi_def_cfa_offset 16
-; CHECK-NEXT: .cfi_offset w30, -16
-; CHECK-NEXT: adrp x8, .LCPI4_0
-; CHECK-NEXT: ldr d1, [x8, :lo12:.LCPI4_0]
-; CHECK-NEXT: bl pow
-; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: pow_v1f64:
+; CHECK-SD: // %bb.0:
+; CHECK-SD-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
+; CHECK-SD-NEXT: .cfi_def_cfa_offset 16
+; CHECK-SD-NEXT: .cfi_offset w30, -16
+; CHECK-SD-NEXT: adrp x8, .LCPI4_0
+; CHECK-SD-NEXT: ldr d1, [x8, :lo12:.LCPI4_0]
+; CHECK-SD-NEXT: bl pow
+; CHECK-SD-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: pow_v1f64:
+; CHECK-GI: // %bb.0:
+; CHECK-GI-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
+; CHECK-GI-NEXT: .cfi_def_cfa_offset 16
+; CHECK-GI-NEXT: .cfi_offset w30, -16
+; CHECK-GI-NEXT: mov x8, #34079 // =0x851f
+; CHECK-GI-NEXT: movk x8, #20971, lsl #16
+; CHECK-GI-NEXT: movk x8, #7864, lsl #32
+; CHECK-GI-NEXT: movk x8, #16393, lsl #48
+; CHECK-GI-NEXT: fmov d1, x8
+; CHECK-GI-NEXT: bl pow
+; CHECK-GI-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
+; CHECK-GI-NEXT: ret
%c = call <1 x double> @llvm.pow.v1f64(<1 x double> %x, <1 x double> <double 3.140000e+00>)
ret <1 x double> %c
}
diff --git a/llvm/test/CodeGen/AArch64/neon-compare-instructions.ll b/llvm/test/CodeGen/AArch64/neon-compare-instructions.ll
index 8c8fde7934b89..be2efccd2432a 100644
--- a/llvm/test/CodeGen/AArch64/neon-compare-instructions.ll
+++ b/llvm/test/CodeGen/AArch64/neon-compare-instructions.ll
@@ -2503,8 +2503,7 @@ define <4 x i32> @fcmal4xfloat(<4 x float> %A, <4 x float> %B) {
;
; CHECK-GI-LABEL: fcmal4xfloat:
; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: mov w8, #1 // =0x1
-; CHECK-GI-NEXT: dup v0.2s, w8
+; CHECK-GI-NEXT: movi v0.2s, #1
; CHECK-GI-NEXT: mov v0.d[1], v0.d[0]
; CHECK-GI-NEXT: shl v0.4s, v0.4s, #31
; CHECK-GI-NEXT: cmlt v0.4s, v0.4s, #0
diff --git a/llvm/test/CodeGen/AArch64/rem-by-const.ll b/llvm/test/CodeGen/AArch64/rem-by-const.ll
index 927d46612f443..b6e06003c7c72 100644
--- a/llvm/test/CodeGen/AArch64/rem-by-const.ll
+++ b/llvm/test/CodeGen/AArch64/rem-by-const.ll
@@ -929,7 +929,7 @@ define <4 x i8> @sv4i8_7(<4 x i8> %d, <4 x i8> %e) {
; CHECK-GI-NEXT: mov v3.b[3], w8
; CHECK-GI-NEXT: uzp1 v1.8b, v2.8b, v0.8b
; CHECK-GI-NEXT: neg v2.8b, v3.8b
-; CHECK-GI-NEXT: dup v3.4h, w9
+; CHECK-GI-NEXT: movi v3.4h, #7
; CHECK-GI-NEXT: sshl v1.8b, v1.8b, v2.8b
; CHECK-GI-NEXT: neg v2.8b, v4.8b
; CHECK-GI-NEXT: ushl v2.8b, v1.8b, v2.8b
@@ -980,10 +980,9 @@ define <4 x i8> @sv4i8_100(<4 x i8> %d, <4 x i8> %e) {
; CHECK-GI-NEXT: mov v3.b[2], w8
; CHECK-GI-NEXT: sshr v1.4h, v1.4h, #8
; CHECK-GI-NEXT: mov v3.b[3], w8
-; CHECK-GI-NEXT: mov w8, #100 // =0x64
; CHECK-GI-NEXT: uzp1 v1.8b, v1.8b, v0.8b
; CHECK-GI-NEXT: neg v2.8b, v3.8b
-; CHECK-GI-NEXT: dup v3.4h, w8
+; CHECK-GI-NEXT: movi v3.4h, #100
; CHECK-GI-NEXT: sshl v1.8b, v1.8b, v2.8b
; CHECK-GI-NEXT: neg v2.8b, v4.8b
; CHECK-GI-NEXT: ushl v2.8b, v1.8b, v2.8b
@@ -1414,12 +1413,11 @@ define <4 x i8> @uv4i8_7(<4 x i8> %d, <4 x i8> %e) {
; CHECK-GI-NEXT: ushl v2.8b, v2.8b, v3.8b
; CHECK-GI-NEXT: ushll v2.8h, v2.8b, #0
; CHECK-GI-NEXT: mov v4.b[3], w8
-; CHECK-GI-NEXT: mov w8, #7 // =0x7
; CHECK-GI-NEXT: usra v2.4h, v1.4h, #8
; CHECK-GI-NEXT: uzp1 v1.8b, v2.8b, v0.8b
; CHECK-GI-NEXT: neg v2.8b, v4.8b
; CHECK-GI-NEXT: ushl v1.8b, v1.8b, v2.8b
-; CHECK-GI-NEXT: dup v2.4h, w8
+; CHECK-GI-NEXT: movi v2.4h, #7
; CHECK-GI-NEXT: ushll v1.8h, v1.8b, #0
; CHECK-GI-NEXT: mls v0.4h, v1.4h, v2.4h
; CHECK-GI-NEXT: ret
@@ -1457,11 +1455,10 @@ define <4 x i8> @uv4i8_100(<4 x i8> %d, <4 x i8> %e) {
; CHECK-GI-NEXT: mov v3.b[2], w8
; CHECK-GI-NEXT: ushr v1.4h, v1.4h, #8
; CHECK-GI-NEXT: mov v3.b[3], w8
-; CHECK-GI-NEXT: mov w8, #100 // =0x64
; CHECK-GI-NEXT: uzp1 v1.8b, v1.8b, v0.8b
; CHECK-GI-NEXT: neg v2.8b, v3.8b
; CHECK-GI-NEXT: ushl v1.8b, v1.8b, v2.8b
-; CHECK-GI-NEXT: dup v2.4h, w8
+; CHECK-GI-NEXT: movi v2.4h, #100
; CHECK-GI-NEXT: ushll v1.8h, v1.8b, #0
; CHECK-GI-NEXT: mls v0.4h, v1.4h, v2.4h
; CHECK-GI-NEXT: ret
@@ -1595,10 +1592,9 @@ define <2 x i16> @sv2i16_7(<2 x i16> %d, <2 x i16> %e) {
; CHECK-GI-NEXT: uzp1 v1.4h, v1.4h, v0.4h
; CHECK-GI-NEXT: mov v3.h[1], w8
; CHECK-GI-NEXT: neg v2.4h, v2.4h
-; CHECK-GI-NEXT: mov w8, #7 // =0x7
; CHECK-GI-NEXT: sshl v1.4h, v1.4h, v2.4h
; CHECK-GI-NEXT: neg v2.4h, v3.4h
-; CHECK-GI-NEXT: dup v3.2s, w8
+; CHECK-GI-NEXT: movi v3.2s, #7
; CHECK-GI-NEXT: ushl v2.4h, v1.4h, v2.4h
; CHECK-GI-NEXT: ushll v1.4s, v1.4h, #0
; CHECK-GI-NEXT: ushll v2.4s, v2.4h, #0
@@ -1644,10 +1640,9 @@ define <2 x i16> @sv2i16_100(<2 x i16> %d, <2 x i16> %e) {
; CHECK-GI-NEXT: uzp1 v1.4h, v1.4h, v0.4h
; CHECK-GI-NEXT: mov v3.h[1], w8
; CHECK-GI-NEXT: neg v2.4h, v2.4h
-; CHECK-GI-NEXT: mov w8, #100 // =0x64
; CHECK-GI-NEXT: sshl v1.4h, v1.4h, v2.4h
; CHECK-GI-NEXT: neg v2.4h, v3.4h
-; CHECK-GI-NEXT: dup v3.2s, w8
+; CHECK-GI-NEXT: movi v3.2s, #100
; CHECK-GI-NEXT: ushl v2.4h, v1.4h, v2.4h
; CHECK-GI-NEXT: ushll v1.4s, v1.4h, #0
; CHECK-GI-NEXT: ushll v2.4s, v2.4h, #0
@@ -1937,12 +1932,11 @@ define <2 x i16> @uv2i16_7(<2 x i16> %d, <2 x i16> %e) {
; CHECK-GI-NEXT: fmov s3, w8
; CHECK-GI-NEXT: ushll v2.4s, v2.4h, #0
; CHECK-GI-NEXT: mov v3.h[1], w8
-; CHECK-GI-NEXT: mov w8, #7 // =0x7
; CHECK-GI-NEXT: usra v2.2s, v1.2s, #16
; CHECK-GI-NEXT: uzp1 v1.4h, v2.4h, v0.4h
; CHECK-GI-NEXT: neg v2.4h, v3.4h
; CHECK-GI-NEXT: ushl v1.4h, v1.4h, v2.4h
-; CHECK-GI-NEXT: dup v2.2s, w8
+; CHECK-GI-NEXT: movi v2.2s, #7
; CHECK-GI-NEXT: ushll v1.4s, v1.4h, #0
; CHECK-GI-NEXT: mls v0.2s, v1.2s, v2.2s
; CHECK-GI-NEXT: ret
@@ -1982,12 +1976,11 @@ define <2 x i16> @uv2i16_100(<2 x i16> %d, <2 x i16> %e) {
; CHECK-GI-NEXT: mul v1.2s, v1.2s, v2.2s
; CHECK-GI-NEXT: fmov s2, w8
; CHECK-GI-NEXT: mov v2.h[1], w8
-; CHECK-GI-NEXT: mov w8, #100 // =0x64
; CHECK-GI-NEXT: ushr v1.2s, v1.2s, #16
; CHECK-GI-NEXT: uzp1 v1.4h, v1.4h, v0.4h
; CHECK-GI-NEXT: neg v2.4h, v2.4h
; CHECK-GI-NEXT: ushl v1.4h, v1.4h, v2.4h
-; CHECK-GI-NEXT: dup v2.2s, w8
+; CHECK-GI-NEXT: movi v2.2s, #100
; CHECK-GI-NEXT: ushll v1.4s, v1.4h, #0
; CHECK-GI-NEXT: mls v0.2s, v1.2s, v2.2s
; CHECK-GI-NEXT: ret
diff --git a/llvm/test/CodeGen/AArch64/select_const.ll b/llvm/test/CodeGen/AArch64/select_const.ll
index 0a73aed803415..2b2b1c1dd2222 100644
--- a/llvm/test/CodeGen/AArch64/select_const.ll
+++ b/llvm/test/CodeGen/AArch64/select_const.ll
@@ -769,14 +769,16 @@ define double @sel_constants_fadd_constant(i1 %cond) {
;
; CHECK-GI-LABEL: sel_constants_fadd_constant:
; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: mov x9, #7378697629483820646 // =0x6666666666666666
-; CHECK-GI-NEXT: adrp x8, .LCPI42_0
-; CHECK-GI-NEXT: movk x9, #16444, lsl #48
-; CHECK-GI-NEXT: ldr d0, [x8, :lo12:.LCPI42_0]
-; CHECK-GI-NEXT: and w8, w0, #0x1
+; CHECK-GI-NEXT: mov x9, #-7378697629483820647 // =0x9999999999999999
+; CHECK-GI-NEXT: mov x8, #7378697629483820646 // =0x6666666666666666
+; CHECK-GI-NEXT: and w10, w0, #0x1
+; CHECK-GI-NEXT: movk x9, #39320
+; CHECK-GI-NEXT: movk x8, #16444, lsl #48
+; CHECK-GI-NEXT: tst w10, #0x1
+; CHECK-GI-NEXT: movk x9, #16369, lsl #48
+; CHECK-GI-NEXT: fmov d0, x8
; CHECK-GI-NEXT: fmov d1, x9
-; CHECK-GI-NEXT: tst w8, #0x1
-; CHECK-GI-NEXT: fcsel d0, d0, d1, ne
+; CHECK-GI-NEXT: fcsel d0, d1, d0, ne
; CHECK-GI-NEXT: ret
%sel = select i1 %cond, double -4.0, double 23.3
%bo = fadd double %sel, 5.1
@@ -797,14 +799,16 @@ define double @sel_constants_fsub_constant(i1 %cond) {
;
; CHECK-GI-LABEL: sel_constants_fsub_constant:
; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: adrp x8, .LCPI43_0
-; CHECK-GI-NEXT: and w9, w0, #0x1
-; CHECK-GI-NEXT: ldr d0, [x8, :lo12:.LCPI43_0]
; CHECK-GI-NEXT: mov x8, #3689348814741910323 // =0x3333333333333333
-; CHECK-GI-NEXT: tst w9, #0x1
-; CHECK-GI-NEXT: movk x8, #49186, lsl #48
+; CHECK-GI-NEXT: mov x9, #3689348814741910323 // =0x3333333333333333
+; CHECK-GI-NEXT: and w10, w0, #0x1
+; CHECK-GI-NEXT: movk x8, #13108
+; CHECK-GI-NEXT: movk x9, #49186, lsl #48
+; CHECK-GI-NEXT: tst w10, #0x1
+; CHECK-GI-NEXT: movk x8, #16434, lsl #48
+; CHECK-GI-NEXT: fmov d0, x9
; CHECK-GI-NEXT: fmov d1, x8
-; CHECK-GI-NEXT: fcsel d0, d1, d0, ne
+; CHECK-GI-NEXT: fcsel d0, d0, d1, ne
; CHECK-GI-NEXT: ret
%sel = select i1 %cond, double -4.0, double 23.3
%bo = fsub double %sel, 5.1
@@ -825,14 +829,16 @@ define double @fsub_constant_sel_constants(i1 %cond) {
;
; CHECK-GI-LABEL: fsub_constant_sel_constants:
; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: adrp x8, .LCPI44_0
-; CHECK-GI-NEXT: and w9, w0, #0x1
-; CHECK-GI-NEXT: ldr d0, [x8, :lo12:.LCPI44_0]
; CHECK-GI-NEXT: mov x8, #3689348814741910323 // =0x3333333333333333
-; CHECK-GI-NEXT: tst w9, #0x1
-; CHECK-GI-NEXT: movk x8, #16418, lsl #48
+; CHECK-GI-NEXT: mov x9, #3689348814741910323 // =0x3333333333333333
+; CHECK-GI-NEXT: and w10, w0, #0x1
+; CHECK-GI-NEXT: movk x8, #13108
+; CHECK-GI-NEXT: movk x9, #16418, lsl #48
+; CHECK-GI-NEXT: tst w10, #0x1
+; CHECK-GI-NEXT: movk x8, #49202, lsl #48
+; CHECK-GI-NEXT: fmov d0, x9
; CHECK-GI-NEXT: fmov d1, x8
-; CHECK-GI-NEXT: fcsel d0, d1, d0, ne
+; CHECK-GI-NEXT: fcsel d0, d0, d1, ne
; CHECK-GI-NEXT: ret
%sel = select i1 %cond, double -4.0, double 23.3
%bo = fsub double 5.1, %sel
@@ -853,14 +859,17 @@ define double @sel_constants_fmul_constant(i1 %cond) {
;
; CHECK-GI-LABEL: sel_constants_fmul_constant:
; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: adrp x8, .LCPI45_0
-; CHECK-GI-NEXT: and w9, w0, #0x1
-; CHECK-GI-NEXT: ldr d0, [x8, :lo12:.LCPI45_0]
-; CHECK-GI-NEXT: mov x8, #7378697629483820646 // =0x6666666666666666
-; CHECK-GI-NEXT: tst w9, #0x1
-; CHECK-GI-NEXT: movk x8, #49204, lsl #48
+; CHECK-GI-NEXT: mov x8, #60293 // =0xeb85
+; CHECK-GI-NEXT: mov x9, #7378697629483820646 // =0x6666666666666666
+; CHECK-GI-NEXT: and w10, w0, #0x1
+; CHECK-GI-NEXT: movk x8, #47185, lsl #16
+; CHECK-GI-NEXT: movk x9, #49204, lsl #48
+; CHECK-GI-NEXT: tst w10, #0x1
+; CHECK-GI-NEXT: movk x8, #46366, lsl #32
+; CHECK-GI-NEXT: fmov d0, x9
+; CHECK-GI-NEXT: movk x8, #16477, lsl #48
; CHECK-GI-NEXT: fmov d1, x8
-; CHECK-GI-NEXT: fcsel d0, d1, d0, ne
+; CHECK-GI-NEXT: fcsel d0, d0, d1, ne
; CHECK-GI-NEXT: ret
%sel = select i1 %cond, double -4.0, double 23.3
%bo = fmul double %sel, 5.1
@@ -880,13 +889,18 @@ define double @sel_constants_fdiv_constant(i1 %cond) {
;
; CHECK-GI-LABEL: sel_constants_fdiv_constant:
; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: adrp x8, .LCPI46_1
-; CHECK-GI-NEXT: adrp x9, .LCPI46_0
-; CHECK-GI-NEXT: ldr d0, [x8, :lo12:.LCPI46_1]
-; CHECK-GI-NEXT: ldr d1, [x9, :lo12:.LCPI46_0]
+; CHECK-GI-NEXT: mov x9, #17991 // =0x4647
+; CHECK-GI-NEXT: mov x10, #6426 // =0x191a
; CHECK-GI-NEXT: and w8, w0, #0x1
+; CHECK-GI-NEXT: movk x9, #17990, lsl #16
+; CHECK-GI-NEXT: movk x10, #6425, lsl #16
; CHECK-GI-NEXT: tst w8, #0x1
-; CHECK-GI-NEXT: fcsel d0, d1, d0, ne
+; CHECK-GI-NEXT: movk x9, #17990, lsl #32
+; CHECK-GI-NEXT: movk x10, #6425, lsl #32
+; CHECK-GI-NEXT: movk x9, #16402, lsl #48
+; CHECK-GI-NEXT: movk x10, #49129, lsl #48
+; CHECK-GI-NEXT: csel x8, x10, x9, ne
+; CHECK-GI-NEXT: fmov d0, x8
; CHECK-GI-NEXT: ret
%sel = select i1 %cond, double -4.0, double 23.3
%bo = fdiv double %sel, 5.1
@@ -907,14 +921,17 @@ define double @fdiv_constant_sel_constants(i1 %cond) {
;
; CHECK-GI-LABEL: fdiv_constant_sel_constants:
; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: adrp x8, .LCPI47_0
-; CHECK-GI-NEXT: and w9, w0, #0x1
-; CHECK-GI-NEXT: ldr d0, [x8, :lo12:.LCPI47_0]
-; CHECK-GI-NEXT: mov x8, #7378697629483820646 // =0x6666666666666666
-; CHECK-GI-NEXT: tst w9, #0x1
-; CHECK-GI-NEXT: movk x8, #49140, lsl #48
+; CHECK-GI-NEXT: mov x8, #9000 // =0x2328
+; CHECK-GI-NEXT: mov x9, #7378697629483820646 // =0x6666666666666666
+; CHECK-GI-NEXT: and w10, w0, #0x1
+; CHECK-GI-NEXT: movk x8, #5344, lsl #16
+; CHECK-GI-NEXT: movk x9, #49140, lsl #48
+; CHECK-GI-NEXT: tst w10, #0x1
+; CHECK-GI-NEXT: movk x8, #1125, lsl #32
+; CHECK-GI-NEXT: fmov d0, x9
+; CHECK-GI-NEXT: movk x8, #16332, lsl #48
; CHECK-GI-NEXT: fmov d1, x8
-; CHECK-GI-NEXT: fcsel d0, d1, d0, ne
+; CHECK-GI-NEXT: fcsel d0, d0, d1, ne
; CHECK-GI-NEXT: ret
%sel = select i1 %cond, double -4.0, double 23.3
%bo = fdiv double 5.1, %sel
@@ -933,11 +950,13 @@ define double @sel_constants_frem_constant(i1 %cond) {
;
; CHECK-GI-LABEL: sel_constants_frem_constant:
; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: adrp x8, .LCPI48_0
+; CHECK-GI-NEXT: mov x8, #3689348814741910323 // =0x3333333333333333
; CHECK-GI-NEXT: fmov d0, #-4.00000000
-; CHECK-GI-NEXT: ldr d1, [x8, :lo12:.LCPI48_0]
-; CHECK-GI-NEXT: and w8, w0, #0x1
-; CHECK-GI-NEXT: tst w8, #0x1
+; CHECK-GI-NEXT: and w9, w0, #0x1
+; CHECK-GI-NEXT: movk x8, #13112
+; CHECK-GI-NEXT: tst w9, #0x1
+; CHECK-GI-NEXT: movk x8, #16391, lsl #48
+; CHECK-GI-NEXT: fmov d1, x8
; CHECK-GI-NEXT: fcsel d0, d0, d1, ne
; CHECK-GI-NEXT: ret
%sel = select i1 %cond, double -4.0, double 23.3
@@ -959,14 +978,16 @@ define double @frem_constant_sel_constants(i1 %cond) {
;
; CHECK-GI-LABEL: frem_constant_sel_constants:
; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: adrp x8, .LCPI49_0
-; CHECK-GI-NEXT: and w9, w0, #0x1
-; CHECK-GI-NEXT: ldr d0, [x8, :lo12:.LCPI49_0]
-; CHECK-GI-NEXT: mov x8, #7378697629483820646 // =0x6666666666666666
-; CHECK-GI-NEXT: tst w9, #0x1
-; CHECK-GI-NEXT: movk x8, #16404, lsl #48
+; CHECK-GI-NEXT: mov x8, #-7378697629483820647 // =0x9999999999999999
+; CHECK-GI-NEXT: mov x9, #7378697629483820646 // =0x6666666666666666
+; CHECK-GI-NEXT: and w10, w0, #0x1
+; CHECK-GI-NEXT: movk x8, #39320
+; CHECK-GI-NEXT: movk x9, #16404, lsl #48
+; CHECK-GI-NEXT: tst w10, #0x1
+; CHECK-GI-NEXT: movk x8, #16369, lsl #48
+; CHECK-GI-NEXT: fmov d0, x9
; CHECK-GI-NEXT: fmov d1, x8
-; CHECK-GI-NEXT: fcsel d0, d0, d1, ne
+; CHECK-GI-NEXT: fcsel d0, d1, d0, ne
; CHECK-GI-NEXT: ret
%sel = select i1 %cond, double -4.0, double 23.3
%bo = frem double 5.1, %sel
diff --git a/llvm/test/CodeGen/AArch64/vecreduce-fadd.ll b/llvm/test/CodeGen/AArch64/vecreduce-fadd.ll
index 40925da0557ec..9436d1561675b 100644
--- a/llvm/test/CodeGen/AArch64/vecreduce-fadd.ll
+++ b/llvm/test/CodeGen/AArch64/vecreduce-fadd.ll
@@ -82,10 +82,9 @@ define half @add_v3HalfH(<3 x half> %bin.rdx) {
;
; CHECK-GI-FP16-LABEL: add_v3HalfH:
; CHECK-GI-FP16: // %bb.0:
-; CHECK-GI-FP16-NEXT: adrp x8, .LCPI2_0
; CHECK-GI-FP16-NEXT: // kill: def $d0 killed $d0 def $q0
-; CHECK-GI-FP16-NEXT: ldr h1, [x8, :lo12:.LCPI2_0]
-; CHECK-GI-FP16-NEXT: mov v0.h[3], v1.h[0]
+; CHECK-GI-FP16-NEXT: mov w8, #32768 // =0x8000
+; CHECK-GI-FP16-NEXT: mov v0.h[3], w8
; CHECK-GI-FP16-NEXT: faddp v0.4h, v0.4h, v0.4h
; CHECK-GI-FP16-NEXT: faddp h0, v0.2h
; CHECK-GI-FP16-NEXT: ret
>From 0fbaf2bc6db8711385c88882e3f06bee04bc75e2 Mon Sep 17 00:00:00 2001
From: Ryan Cowan <ryan.cowan at arm.com>
Date: Thu, 29 Jan 2026 11:29:12 +0000
Subject: [PATCH 2/5] Create 32 bit g_constants only & add GISel equivalents
for bitcast_fpimm_to_{i32,i64}
---
llvm/lib/Target/AArch64/AArch64InstrInfo.td | 5 +
.../GISel/AArch64InstructionSelector.cpp | 169 ++++++++++--------
.../AArch64/GISel/AArch64RegisterBankInfo.cpp | 10 +-
.../GlobalISel/preselect-process-phis.mir | 2 +-
.../AArch64/GlobalISel/select-constant.mir | 2 +-
.../CodeGen/AArch64/GlobalISel/select-dup.mir | 2 +-
6 files changed, 111 insertions(+), 79 deletions(-)
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index 212c3891e1387..afc6d56467aaa 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -2652,6 +2652,11 @@ return CurDAG->getTargetConstant(
N->getValueAPF().bitcastToAPInt().getZExtValue(), SDLoc(N), MVT::i64);
}]>;
+def gi_bitcast_fpimm_to_i32 : GICustomOperandRenderer<"renderBitcastFPImm">,
+ GISDNodeXFormEquiv<bitcast_fpimm_to_i32>;
+def gi_bitcast_fpimm_to_i64 : GICustomOperandRenderer<"renderBitcastFPImm">,
+ GISDNodeXFormEquiv<bitcast_fpimm_to_i64>;
+
def : Pat<(f32 fpimm:$in),
(COPY_TO_REGCLASS (MOVi32imm (bitcast_fpimm_to_i32 f32:$in)), FPR32)>;
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
index b922b7decb1b3..29f0a0852ec7c 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
@@ -496,6 +496,8 @@ class AArch64InstructionSelector : public InstructionSelector {
int OpIdx = -1) const;
void renderFPImm64(MachineInstrBuilder &MIB, const MachineInstr &MI,
int OpIdx = -1) const;
+ void renderBitcastFPImm(MachineInstrBuilder &MIB, const MachineInstr &MI,
+ int OpIdx = -1) const;
void renderFPImm32SIMDModImmType4(MachineInstrBuilder &MIB,
const MachineInstr &MI,
int OpIdx = -1) const;
@@ -2670,56 +2672,58 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
case TargetOpcode::G_CONSTANT: {
const bool isFP = Opcode == TargetOpcode::G_FCONSTANT;
- const LLT s8 = LLT::scalar(8);
- const LLT s16 = LLT::scalar(16);
- const LLT s32 = LLT::scalar(32);
- const LLT s64 = LLT::scalar(64);
- const LLT s128 = LLT::scalar(128);
- const LLT p0 = LLT::pointer(0, 64);
+ // const LLT s8 = LLT::scalar(8);
+ // const LLT s16 = LLT::scalar(16);
+ // const LLT s32 = LLT::scalar(32);
+ // const LLT s64 = LLT::scalar(64);
+ // const LLT s128 = LLT::scalar(128);
+ // const LLT p0 = LLT::pointer(0, 64);
const Register DefReg = I.getOperand(0).getReg();
const LLT DefTy = MRI.getType(DefReg);
const unsigned DefSize = DefTy.getSizeInBits();
const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI);
- // FIXME: Redundant check, but even less readable when factored out.
- if (isFP) {
- if (Ty != s16 && Ty != s32 && Ty != s64 && Ty != s128) {
- LLVM_DEBUG(dbgs() << "Unable to materialize FP " << Ty
- << " constant, expected: " << s16 << " or " << s32
- << " or " << s64 << " or " << s128 << '\n');
- return false;
- }
-
- if (RB.getID() != AArch64::FPRRegBankID) {
- LLVM_DEBUG(dbgs() << "Unable to materialize FP " << Ty
- << " constant on bank: " << RB
- << ", expected: FPR\n");
- return false;
- }
-
- // The case when we have 0.0 is covered by tablegen. Reject it here so we
- // can be sure tablegen works correctly and isn't rescued by this code.
- // 0.0 is not covered by tablegen for FP128. So we will handle this
- // scenario in the code here.
- if (DefSize != 128 && I.getOperand(1).getFPImm()->isExactlyValue(0.0))
- return false;
- } else {
- // s32 and s64 are covered by tablegen.
- if (Ty != p0 && Ty != s8 && Ty != s16) {
- LLVM_DEBUG(dbgs() << "Unable to materialize integer " << Ty
- << " constant, expected: " << s32 << ", " << s64
- << ", or " << p0 << '\n');
- return false;
- }
-
- if (RB.getID() != AArch64::GPRRegBankID) {
- LLVM_DEBUG(dbgs() << "Unable to materialize integer " << Ty
- << " constant on bank: " << RB
- << ", expected: GPR\n");
- return false;
- }
- }
+ // // FIXME: Redundant check, but even less readable when factored out.
+ // if (isFP) {
+ // if (Ty != s16 && Ty != s32 && Ty != s64 && Ty != s128) {
+ // LLVM_DEBUG(dbgs() << "Unable to materialize FP " << Ty
+ // << " constant, expected: " << s16 << " or " <<
+ // s32
+ // << " or " << s64 << " or " << s128 << '\n');
+ // return false;
+ // }
+
+ // if (RB.getID() != AArch64::FPRRegBankID) {
+ // LLVM_DEBUG(dbgs() << "Unable to materialize FP " << Ty
+ // << " constant on bank: " << RB
+ // << ", expected: FPR\n");
+ // return false;
+ // }
+
+ // The case when we have 0.0 is covered by tablegen. Reject it here so we
+ // can be sure tablegen works correctly and isn't rescued by this code.
+ // 0.0 is not covered by tablegen for FP128. So we will handle this
+ // scenario in the code here.
+ // if (isFP && DefSize != 128 &&
+ // I.getOperand(1).getFPImm()->isExactlyValue(0.0))
+ // return false;
+ // } else {
+ // // s32 and s64 are covered by tablegen.
+ // if (Ty != p0 && Ty != s8 && Ty != s16) {
+ // LLVM_DEBUG(dbgs() << "Unable to materialize integer " << Ty
+ // << " constant, expected: " << s32 << ", " << s64
+ // << ", or " << p0 << '\n');
+ // return false;
+ // }
+
+ // if (RB.getID() != AArch64::GPRRegBankID) {
+ // LLVM_DEBUG(dbgs() << "Unable to materialize integer " << Ty
+ // << " constant on bank: " << RB
+ // << ", expected: GPR\n");
+ // return false;
+ // }
+ // }
if (isFP) {
const TargetRegisterClass &FPRRC = *getRegClassForTypeOnBank(DefTy, RB);
@@ -2751,39 +2755,44 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
return RBI.constrainGenericRegister(DefReg, FPRRC, MRI);
}
}
+ }
- assert((DefSize == 32 || DefSize == 64) && "Unexpected const def size");
- // Either emit a FMOV, or emit a copy to emit a normal mov.
- const Register DefGPRReg = MRI.createVirtualRegister(
- DefSize == 32 ? &AArch64::GPR32RegClass : &AArch64::GPR64RegClass);
- MachineOperand &RegOp = I.getOperand(0);
- RegOp.setReg(DefGPRReg);
- MIB.setInsertPt(MIB.getMBB(), std::next(I.getIterator()));
- MIB.buildCopy({DefReg}, {DefGPRReg});
-
- if (!RBI.constrainGenericRegister(DefReg, FPRRC, MRI)) {
- LLVM_DEBUG(dbgs() << "Failed to constrain G_FCONSTANT def operand\n");
- return false;
- }
-
- MachineOperand &ImmOp = I.getOperand(1);
- // FIXME: Is going through int64_t always correct?
- ImmOp.ChangeToImmediate(
- ImmOp.getFPImm()->getValueAPF().bitcastToAPInt().getZExtValue());
- } else if (I.getOperand(1).isCImm()) {
- uint64_t Val = I.getOperand(1).getCImm()->getZExtValue();
- I.getOperand(1).ChangeToImmediate(Val);
- } else if (I.getOperand(1).isImm()) {
- uint64_t Val = I.getOperand(1).getImm();
- I.getOperand(1).ChangeToImmediate(Val);
- }
-
- const unsigned MovOpc =
- DefSize == 64 ? AArch64::MOVi64imm : AArch64::MOVi32imm;
- I.setDesc(TII.get(MovOpc));
- constrainSelectedInstRegOperands(I, TII, TRI, RBI);
- return true;
+ return false;
}
+
+ // assert((DefSize == 32 || DefSize == 64) && "Unexpected const def
+ // size");
+ // // Either emit a FMOV, or emit a copy to emit a normal mov.
+ // const Register DefGPRReg = MRI.createVirtualRegister(
+ // DefSize == 32 ? &AArch64::GPR32RegClass : &AArch64::GPR64RegClass);
+ // MachineOperand &RegOp = I.getOperand(0);
+ // RegOp.setReg(DefGPRReg);
+ // MIB.setInsertPt(MIB.getMBB(), std::next(I.getIterator()));
+ // MIB.buildCopy({DefReg}, {DefGPRReg});
+
+ // if (!RBI.constrainGenericRegister(DefReg, FPRRC, MRI)) {
+ // LLVM_DEBUG(dbgs() << "Failed to constrain G_FCONSTANT def
+ // operand\n"); return false;
+ // }
+
+ // MachineOperand &ImmOp = I.getOperand(1);
+ // // FIXME: Is going through int64_t always correct?
+ // ImmOp.ChangeToImmediate(
+ // ImmOp.getFPImm()->getValueAPF().bitcastToAPInt().getZExtValue());
+ // } else if (I.getOperand(1).isCImm()) {
+ // uint64_t Val = I.getOperand(1).getCImm()->getZExtValue();
+ // I.getOperand(1).ChangeToImmediate(Val);
+ // } else if (I.getOperand(1).isImm()) {
+ // uint64_t Val = I.getOperand(1).getImm();
+ // I.getOperand(1).ChangeToImmediate(Val);
+ // }
+
+ // const unsigned MovOpc =
+ // DefSize == 64 ? AArch64::MOVi64imm : AArch64::MOVi32imm;
+ // I.setDesc(TII.get(MovOpc));
+ // constrainSelectedInstRegOperands(I, TII, TRI, RBI);
+ // return true;
+ // }
case TargetOpcode::G_EXTRACT: {
Register DstReg = I.getOperand(0).getReg();
Register SrcReg = I.getOperand(1).getReg();
@@ -7920,6 +7929,16 @@ void AArch64InstructionSelector::renderFPImm64(MachineInstrBuilder &MIB,
AArch64_AM::getFP64Imm(MI.getOperand(1).getFPImm()->getValueAPF()));
}
+void AArch64InstructionSelector::renderBitcastFPImm(MachineInstrBuilder &MIB,
+ const MachineInstr &MI,
+ int OpIdx) const {
+ assert(MI.getOpcode() == TargetOpcode::G_FCONSTANT && OpIdx == -1 &&
+ "Expected G_FCONSTANT");
+ const APInt Bits =
+ MI.getOperand(1).getFPImm()->getValueAPF().bitcastToAPInt();
+ MIB.addImm(Bits.getZExtValue());
+}
+
void AArch64InstructionSelector::renderFPImm32SIMDModImmType4(
MachineInstrBuilder &MIB, const MachineInstr &MI, int OpIdx) const {
assert(MI.getOpcode() == TargetOpcode::G_FCONSTANT && OpIdx == -1 &&
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
index ceabe776f768b..6cb645bc0a81b 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
@@ -416,8 +416,16 @@ void AArch64RegisterBankInfo::applyMappingImpl(
Register Dst = MI.getOperand(0).getReg();
if (MRI.getRegBank(Dst) == &AArch64::GPRRegBank) {
const APFloat &Imm = MI.getOperand(1).getFPImm()->getValueAPF();
+ APInt Bits = Imm.bitcastToAPInt();
Builder.setInsertPt(*MI.getParent(), MI.getIterator());
- Builder.buildConstant(Dst, Imm.bitcastToAPInt());
+ if (Bits.getBitWidth() < 32) {
+ Register ExtReg = MRI.createGenericVirtualRegister(LLT::scalar(32));
+ Builder.buildConstant(ExtReg, Bits.zext(32));
+ Builder.buildTrunc(Dst, ExtReg);
+ MRI.setRegBank(ExtReg, AArch64::GPRRegBank);
+ } else {
+ Builder.buildConstant(Dst, Bits);
+ }
MI.eraseFromParent();
return;
}
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/preselect-process-phis.mir b/llvm/test/CodeGen/AArch64/GlobalISel/preselect-process-phis.mir
index 34dbad5a94977..ab04d5bb3bada 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/preselect-process-phis.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/preselect-process-phis.mir
@@ -1,5 +1,5 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
-# RUN: llc -verify-machineinstrs -mtriple aarch64--- -run-pass=instruction-select -global-isel-abort=1 %s -o - | FileCheck %s
+# RUN: llc -verify-machineinstrs -mtriple aarch64--- --run-pass=regbankselect --run-pass=instruction-select -global-isel-abort=1 %s -o - | FileCheck %s
---
name: test_loop_phi_fpr_to_gpr
alignment: 4
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-constant.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-constant.mir
index 417ac91113f2c..601ee70bd3e3d 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/select-constant.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-constant.mir
@@ -1,5 +1,5 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
-# RUN: llc -mtriple=aarch64-- -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s
+# RUN: llc -mtriple=aarch64-- -run-pass=regbankselect -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s
--- |
target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-dup.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-dup.mir
index cf2bab78fe5a6..60a9c6e0c1490 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/select-dup.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-dup.mir
@@ -1,5 +1,5 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
-# RUN: llc -mtriple=aarch64 -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s
+# RUN: llc -mtriple=aarch64 -run-pass=regbankselect -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s
#
# GPR variants should not use INSERT_SUBREG. FPR variants (DUP<ty>lane) should.
>From 6f73cc2a3940d31e177629224a625078bad56189 Mon Sep 17 00:00:00 2001
From: Ryan Cowan <ryan.cowan at arm.com>
Date: Thu, 29 Jan 2026 14:16:06 +0000
Subject: [PATCH 3/5] Add handling for pointers
---
.../GISel/AArch64InstructionSelector.cpp | 109 ++++--------------
.../GlobalISel/preselect-process-phis.mir | 12 +-
.../CodeGen/AArch64/GlobalISel/select-dup.mir | 2 +-
.../GlobalISel/select-fp16-fconstant.mir | 6 +-
.../CodeGen/AArch64/GlobalISel/select-imm.mir | 33 +++---
.../test/CodeGen/AArch64/arm64-fp-imm-size.ll | 16 +--
6 files changed, 60 insertions(+), 118 deletions(-)
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
index 29f0a0852ec7c..72acf26cb46ca 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
@@ -2672,59 +2672,11 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
case TargetOpcode::G_CONSTANT: {
const bool isFP = Opcode == TargetOpcode::G_FCONSTANT;
- // const LLT s8 = LLT::scalar(8);
- // const LLT s16 = LLT::scalar(16);
- // const LLT s32 = LLT::scalar(32);
- // const LLT s64 = LLT::scalar(64);
- // const LLT s128 = LLT::scalar(128);
- // const LLT p0 = LLT::pointer(0, 64);
-
const Register DefReg = I.getOperand(0).getReg();
const LLT DefTy = MRI.getType(DefReg);
const unsigned DefSize = DefTy.getSizeInBits();
const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI);
- // // FIXME: Redundant check, but even less readable when factored out.
- // if (isFP) {
- // if (Ty != s16 && Ty != s32 && Ty != s64 && Ty != s128) {
- // LLVM_DEBUG(dbgs() << "Unable to materialize FP " << Ty
- // << " constant, expected: " << s16 << " or " <<
- // s32
- // << " or " << s64 << " or " << s128 << '\n');
- // return false;
- // }
-
- // if (RB.getID() != AArch64::FPRRegBankID) {
- // LLVM_DEBUG(dbgs() << "Unable to materialize FP " << Ty
- // << " constant on bank: " << RB
- // << ", expected: FPR\n");
- // return false;
- // }
-
- // The case when we have 0.0 is covered by tablegen. Reject it here so we
- // can be sure tablegen works correctly and isn't rescued by this code.
- // 0.0 is not covered by tablegen for FP128. So we will handle this
- // scenario in the code here.
- // if (isFP && DefSize != 128 &&
- // I.getOperand(1).getFPImm()->isExactlyValue(0.0))
- // return false;
- // } else {
- // // s32 and s64 are covered by tablegen.
- // if (Ty != p0 && Ty != s8 && Ty != s16) {
- // LLVM_DEBUG(dbgs() << "Unable to materialize integer " << Ty
- // << " constant, expected: " << s32 << ", " << s64
- // << ", or " << p0 << '\n');
- // return false;
- // }
-
- // if (RB.getID() != AArch64::GPRRegBankID) {
- // LLVM_DEBUG(dbgs() << "Unable to materialize integer " << Ty
- // << " constant on bank: " << RB
- // << ", expected: GPR\n");
- // return false;
- // }
- // }
-
if (isFP) {
const TargetRegisterClass &FPRRC = *getRegClassForTypeOnBank(DefTy, RB);
// For 16, 64, and 128b values, emit a constant pool load.
@@ -2755,44 +2707,33 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
return RBI.constrainGenericRegister(DefReg, FPRRC, MRI);
}
}
- }
+ }
- return false;
- }
+ if (DefTy.isPointer()) {
+ if (DefSize != 64)
+ return false;
- // assert((DefSize == 32 || DefSize == 64) && "Unexpected const def
- // size");
- // // Either emit a FMOV, or emit a copy to emit a normal mov.
- // const Register DefGPRReg = MRI.createVirtualRegister(
- // DefSize == 32 ? &AArch64::GPR32RegClass : &AArch64::GPR64RegClass);
- // MachineOperand &RegOp = I.getOperand(0);
- // RegOp.setReg(DefGPRReg);
- // MIB.setInsertPt(MIB.getMBB(), std::next(I.getIterator()));
- // MIB.buildCopy({DefReg}, {DefGPRReg});
-
- // if (!RBI.constrainGenericRegister(DefReg, FPRRC, MRI)) {
- // LLVM_DEBUG(dbgs() << "Failed to constrain G_FCONSTANT def
- // operand\n"); return false;
- // }
-
- // MachineOperand &ImmOp = I.getOperand(1);
- // // FIXME: Is going through int64_t always correct?
- // ImmOp.ChangeToImmediate(
- // ImmOp.getFPImm()->getValueAPF().bitcastToAPInt().getZExtValue());
- // } else if (I.getOperand(1).isCImm()) {
- // uint64_t Val = I.getOperand(1).getCImm()->getZExtValue();
- // I.getOperand(1).ChangeToImmediate(Val);
- // } else if (I.getOperand(1).isImm()) {
- // uint64_t Val = I.getOperand(1).getImm();
- // I.getOperand(1).ChangeToImmediate(Val);
- // }
-
- // const unsigned MovOpc =
- // DefSize == 64 ? AArch64::MOVi64imm : AArch64::MOVi32imm;
- // I.setDesc(TII.get(MovOpc));
- // constrainSelectedInstRegOperands(I, TII, TRI, RBI);
- // return true;
- // }
+ uint64_t Val = 0;
+ if (I.getOperand(1).isCImm())
+ Val = I.getOperand(1).getCImm()->getZExtValue();
+ else if (I.getOperand(1).isImm())
+ Val = I.getOperand(1).getImm();
+ else
+ return false;
+
+ Register TmpReg = MRI.createVirtualRegister(&AArch64::GPR64RegClass);
+ auto Mov = MIB.buildInstr(AArch64::MOVi64imm, {TmpReg}, {}).addImm(Val);
+ MIB.buildCopy({DefReg}, {TmpReg});
+ I.eraseFromParent();
+
+ const TargetRegisterClass &RC = *getRegClassForTypeOnBank(DefTy, RB);
+ if (!RBI.constrainGenericRegister(DefReg, RC, MRI))
+ return false;
+ return constrainSelectedInstRegOperands(*Mov, TII, TRI, RBI);
+ }
+
+ return false;
+ }
case TargetOpcode::G_EXTRACT: {
Register DstReg = I.getOperand(0).getReg();
Register SrcReg = I.getOperand(1).getReg();
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/preselect-process-phis.mir b/llvm/test/CodeGen/AArch64/GlobalISel/preselect-process-phis.mir
index ab04d5bb3bada..b8a9209caa863 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/preselect-process-phis.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/preselect-process-phis.mir
@@ -30,7 +30,7 @@ body: |
; CHECK-NEXT: bb.2:
; CHECK-NEXT: successors: %bb.2(0x80000000)
; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: [[PHI:%[0-9]+]]:gpr32 = PHI [[CSELWr]], %bb.1, %8, %bb.2
+ ; CHECK-NEXT: [[PHI:%[0-9]+]]:gpr32 = PHI [[CSELWr]], %bb.1, %9, %bb.2
; CHECK-NEXT: [[FCVTHSr:%[0-9]+]]:fpr16 = nofpexcept FCVTHSr [[COPY]], implicit $fpcr
; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:fpr32 = SUBREG_TO_REG 0, [[FCVTHSr]], %subreg.hsub
; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr32all = COPY [[SUBREG_TO_REG]]
@@ -154,20 +154,22 @@ body: |
; CHECK-NEXT: bb.3:
; CHECK-NEXT: successors: %bb.4(0x80000000)
; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: %fpr:fpr16 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:gpr32 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:fpr32 = COPY [[DEF]]
+ ; CHECK-NEXT: [[COPY3:%[0-9]+]]:fpr16 = COPY [[COPY2]].hsub
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.4:
; CHECK-NEXT: successors: %bb.5(0x80000000)
; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: %fp_phi:fpr16 = PHI %fpr, %bb.3, [[COPY1]], %bb.2
+ ; CHECK-NEXT: %fp_phi:fpr16 = PHI [[COPY3]], %bb.3, [[COPY1]], %bb.2
; CHECK-NEXT: %gp_phi1:gpr32 = PHI %gpr_1, %bb.3, %gpr_2, %bb.2
; CHECK-NEXT: %gp_phi2:gpr32 = PHI %gpr_1, %bb.3, %gpr_2, %bb.2
; CHECK-NEXT: %gp_phi3:gpr32 = PHI %gpr_1, %bb.3, %gpr_2, %bb.2
; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:fpr32 = SUBREG_TO_REG 0, %fp_phi, %subreg.hsub
- ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gpr32all = COPY [[SUBREG_TO_REG]]
+ ; CHECK-NEXT: [[COPY4:%[0-9]+]]:gpr32all = COPY [[SUBREG_TO_REG]]
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.5:
- ; CHECK-NEXT: %use_fp_phi:gpr32 = PHI %gpr_1, %bb.0, [[COPY2]], %bb.4
+ ; CHECK-NEXT: %use_fp_phi:gpr32 = PHI %gpr_1, %bb.0, [[COPY4]], %bb.4
; CHECK-NEXT: %use_gp_phi1:gpr32 = PHI %gpr_1, %bb.0, %gp_phi1, %bb.4
; CHECK-NEXT: %use_gp_phi2:gpr32 = PHI %gpr_1, %bb.0, %gp_phi2, %bb.4
; CHECK-NEXT: %use_gp_phi3:gpr32 = PHI %gpr_1, %bb.0, %gp_phi3, %bb.4
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-dup.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-dup.mir
index 60a9c6e0c1490..f6822e3dde31a 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/select-dup.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-dup.mir
@@ -444,7 +444,7 @@ body: |
; CHECK-LABEL: name: cst_v2p0
; CHECK: liveins: $w0
; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: %cst:gpr64 = MOVi64imm 3
+ ; CHECK-NEXT: [[MOVi64imm:%[0-9]+]]:gpr64 = MOVi64imm 3
; CHECK-NEXT: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) %const.0
; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) %const.0 :: (load (s128) from constant-pool)
; CHECK-NEXT: $q0 = COPY [[LDRQui]]
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-fp16-fconstant.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-fp16-fconstant.mir
index 5b6726d6e5bf3..0966ea4c33b6a 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/select-fp16-fconstant.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-fp16-fconstant.mir
@@ -39,9 +39,9 @@ tracksRegLiveness: true
body: |
bb.0:
; CHECK-LABEL: name: constant_pool_load
- ; CHECK: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) %const.0
- ; CHECK-NEXT: [[LDRHui:%[0-9]+]]:fpr16 = LDRHui [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) %const.0 :: (load (s16) from constant-pool)
- ; CHECK-NEXT: $h0 = COPY [[LDRHui]]
+ ; CHECK: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 11
+ ; CHECK-NEXT: [[FMOVWHr:%[0-9]+]]:fpr16 = FMOVWHr [[MOVi32imm]]
+ ; CHECK-NEXT: $h0 = COPY [[FMOVWHr]]
; CHECK-NEXT: RET_ReallyLR implicit $h0
%0:fpr(s16) = G_FCONSTANT half 0xH000B
$h0 = COPY %0(s16)
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-imm.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-imm.mir
index 9f02f31a15e32..b9fca21c45246 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/select-imm.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-imm.mir
@@ -90,9 +90,9 @@ body: |
; 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: [[FADDDrr:%[0-9]+]]:fpr64 = nofpexcept FADDDrr [[COPY]], [[LDRDui]], implicit $fpcr
+ ; CHECK-NEXT: [[MOVi64imm:%[0-9]+]]:gpr64 = MOVi64imm 4607173411600762667
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr64 = COPY [[MOVi64imm]]
+ ; CHECK-NEXT: [[FADDDrr:%[0-9]+]]:fpr64 = nofpexcept FADDDrr [[COPY]], [[COPY1]], implicit $fpcr
; CHECK-NEXT: $d0 = COPY [[FADDDrr]]
; CHECK-NEXT: RET_ReallyLR implicit $d0
;
@@ -100,8 +100,9 @@ body: |
; 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: [[FADDDrr:%[0-9]+]]:fpr64 = nofpexcept FADDDrr [[COPY]], [[LDRDl]], implicit $fpcr
+ ; CHECK-TINY-NEXT: [[MOVi64imm:%[0-9]+]]:gpr64 = MOVi64imm 4607173411600762667
+ ; CHECK-TINY-NEXT: [[COPY1:%[0-9]+]]:fpr64 = COPY [[MOVi64imm]]
+ ; CHECK-TINY-NEXT: [[FADDDrr:%[0-9]+]]:fpr64 = nofpexcept FADDDrr [[COPY]], [[COPY1]], implicit $fpcr
; CHECK-TINY-NEXT: $d0 = COPY [[FADDDrr]]
; CHECK-TINY-NEXT: RET_ReallyLR implicit $d0
%0:fpr(s64) = COPY $d0
@@ -126,9 +127,9 @@ body: |
; 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: [[FADDSrr:%[0-9]+]]:fpr32 = nofpexcept FADDSrr [[COPY]], [[LDRSui]], implicit $fpcr
+ ; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1054421999
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr32 = COPY [[MOVi32imm]]
+ ; CHECK-NEXT: [[FADDSrr:%[0-9]+]]:fpr32 = nofpexcept FADDSrr [[COPY]], [[COPY1]], implicit $fpcr
; CHECK-NEXT: $s0 = COPY [[FADDSrr]]
; CHECK-NEXT: RET_ReallyLR implicit $s0
;
@@ -136,8 +137,9 @@ body: |
; 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: [[FADDSrr:%[0-9]+]]:fpr32 = nofpexcept FADDSrr [[COPY]], [[LDRSl]], implicit $fpcr
+ ; CHECK-TINY-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1054421999
+ ; CHECK-TINY-NEXT: [[COPY1:%[0-9]+]]:fpr32 = COPY [[MOVi32imm]]
+ ; CHECK-TINY-NEXT: [[FADDSrr:%[0-9]+]]:fpr32 = nofpexcept FADDSrr [[COPY]], [[COPY1]], implicit $fpcr
; CHECK-TINY-NEXT: $s0 = COPY [[FADDSrr]]
; CHECK-TINY-NEXT: RET_ReallyLR implicit $s0
%0:fpr(s32) = COPY $s0
@@ -162,9 +164,9 @@ body: |
; 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: [[FADDSrr:%[0-9]+]]:fpr32 = nofpexcept FADDSrr [[COPY]], [[LDRSui]], implicit $fpcr
+ ; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1054421999
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr32 = COPY [[MOVi32imm]]
+ ; CHECK-NEXT: [[FADDSrr:%[0-9]+]]:fpr32 = nofpexcept FADDSrr [[COPY]], [[COPY1]], implicit $fpcr
; CHECK-NEXT: $s0 = COPY [[FADDSrr]]
; CHECK-NEXT: RET_ReallyLR implicit $s0
;
@@ -172,8 +174,9 @@ body: |
; 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: [[FADDSrr:%[0-9]+]]:fpr32 = nofpexcept FADDSrr [[COPY]], [[LDRSl]], implicit $fpcr
+ ; CHECK-TINY-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 1054421999
+ ; CHECK-TINY-NEXT: [[COPY1:%[0-9]+]]:fpr32 = COPY [[MOVi32imm]]
+ ; CHECK-TINY-NEXT: [[FADDSrr:%[0-9]+]]:fpr32 = nofpexcept FADDSrr [[COPY]], [[COPY1]], implicit $fpcr
; CHECK-TINY-NEXT: $s0 = COPY [[FADDSrr]]
; CHECK-TINY-NEXT: RET_ReallyLR implicit $s0
%0:fpr(s32) = COPY $s0
diff --git a/llvm/test/CodeGen/AArch64/arm64-fp-imm-size.ll b/llvm/test/CodeGen/AArch64/arm64-fp-imm-size.ll
index db219c926c0f2..78c45c9758e7d 100644
--- a/llvm/test/CodeGen/AArch64/arm64-fp-imm-size.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-fp-imm-size.ll
@@ -94,12 +94,10 @@ define double @foo2_pgso() !prof !14 {
;
; CHECK-GI-LABEL: foo2_pgso:
; CHECK-GI: ; %bb.0:
-; CHECK-GI-NEXT: Lloh2:
-; CHECK-GI-NEXT: adrp x8, lCPI4_0 at PAGE
-; CHECK-GI-NEXT: Lloh3:
-; CHECK-GI-NEXT: ldr d0, [x8, lCPI4_0 at PAGEOFF]
+; CHECK-GI-NEXT: mov x8, #137438887936 ; =0x1fffff0000
+; CHECK-GI-NEXT: movk x8, #65489
+; CHECK-GI-NEXT: fmov d0, x8
; CHECK-GI-NEXT: ret
-; CHECK-GI-NEXT: .loh AdrpLdr Lloh2, Lloh3
ret double 0x1FFFFFFFd1
}
@@ -115,12 +113,10 @@ define float @bar_pgso() !prof !14 {
;
; CHECK-GI-LABEL: bar_pgso:
; CHECK-GI: ; %bb.0:
-; CHECK-GI-NEXT: Lloh4:
-; CHECK-GI-NEXT: adrp x8, lCPI5_0 at PAGE
-; CHECK-GI-NEXT: Lloh5:
-; CHECK-GI-NEXT: ldr s0, [x8, lCPI5_0 at PAGEOFF]
+; CHECK-GI-NEXT: mov w8, #4060 ; =0xfdc
+; CHECK-GI-NEXT: movk w8, #16457, lsl #16
+; CHECK-GI-NEXT: fmov s0, w8
; CHECK-GI-NEXT: ret
-; CHECK-GI-NEXT: .loh AdrpLdr Lloh4, Lloh5
ret float 0x400921FB80000000
}
>From df5ea6f0cd5ee54d15248d66821b8b0536082cef Mon Sep 17 00:00:00 2001
From: Ryan Cowan <ryan.cowan at arm.com>
Date: Fri, 30 Jan 2026 11:21:44 +0000
Subject: [PATCH 4/5] Convert pointers to scalars of the correct size
---
.../GISel/AArch64InstructionSelector.cpp | 35 +++++++------------
.../AArch64/GlobalISel/inttoptr_add.ll | 6 ++--
.../CodeGen/AArch64/GlobalISel/select-dup.mir | 4 ++-
.../CodeGen/AArch64/neon-extadd-extract.ll | 2 +-
4 files changed, 19 insertions(+), 28 deletions(-)
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
index 72acf26cb46ca..b460eaa8a3772 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
@@ -2127,6 +2127,18 @@ bool AArch64InstructionSelector::preISelLower(MachineInstr &I) {
MachineRegisterInfo &MRI = MF.getRegInfo();
switch (I.getOpcode()) {
+ case TargetOpcode::G_CONSTANT: {
+ Register DefReg = I.getOperand(0).getReg();
+ const LLT DefTy = MRI.getType(DefReg);
+ if (!DefTy.isPointer())
+ return false;
+ const unsigned PtrSize = DefTy.getSizeInBits();
+ if (PtrSize != 32 && PtrSize != 64)
+ return false;
+ // Convert pointer typed constants to integers so TableGen can select.
+ MRI.setType(DefReg, LLT::scalar(PtrSize));
+ return true;
+ }
case TargetOpcode::G_STORE: {
bool Changed = contractCrossBankCopyIntoStore(I, MRI);
MachineOperand &SrcOp = I.getOperand(0);
@@ -2709,29 +2721,6 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
}
}
- if (DefTy.isPointer()) {
- if (DefSize != 64)
- return false;
-
- uint64_t Val = 0;
- if (I.getOperand(1).isCImm())
- Val = I.getOperand(1).getCImm()->getZExtValue();
- else if (I.getOperand(1).isImm())
- Val = I.getOperand(1).getImm();
- else
- return false;
-
- Register TmpReg = MRI.createVirtualRegister(&AArch64::GPR64RegClass);
- auto Mov = MIB.buildInstr(AArch64::MOVi64imm, {TmpReg}, {}).addImm(Val);
- MIB.buildCopy({DefReg}, {TmpReg});
- I.eraseFromParent();
-
- const TargetRegisterClass &RC = *getRegClassForTypeOnBank(DefTy, RB);
- if (!RBI.constrainGenericRegister(DefReg, RC, MRI))
- return false;
- return constrainSelectedInstRegOperands(*Mov, TII, TRI, RBI);
- }
-
return false;
}
case TargetOpcode::G_EXTRACT: {
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/inttoptr_add.ll b/llvm/test/CodeGen/AArch64/GlobalISel/inttoptr_add.ll
index 38b9558f426f2..21402fade53dd 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/inttoptr_add.ll
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/inttoptr_add.ll
@@ -4,9 +4,9 @@
define dso_local void @fn() {
; CHECK-LABEL: fn:
; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: mov x8, #4132
-; CHECK-NEXT: mov w9, #1
-; CHECK-NEXT: movk x8, #65489, lsl #16
+; CHECK-NEXT: mov w8, #4132 // =0x1024
+; CHECK-NEXT: mov w9, #1 // =0x1
+; CHECK-NEXT: movk w8, #65489, lsl #16
; CHECK-NEXT: str w9, [x8]
; CHECK-NEXT: ret
entry:
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-dup.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-dup.mir
index f6822e3dde31a..c5bea027403a3 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/select-dup.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-dup.mir
@@ -444,7 +444,9 @@ body: |
; CHECK-LABEL: name: cst_v2p0
; CHECK: liveins: $w0
; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: [[MOVi64imm:%[0-9]+]]:gpr64 = MOVi64imm 3
+ ; CHECK-NEXT: [[MOVi32imm:%[0-9]+]]:gpr32 = MOVi32imm 3
+ ; CHECK-NEXT: %cst:gpr64all = SUBREG_TO_REG 0, [[MOVi32imm]], %subreg.sub_32
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64 = COPY %cst
; CHECK-NEXT: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) %const.0
; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) %const.0 :: (load (s128) from constant-pool)
; CHECK-NEXT: $q0 = COPY [[LDRQui]]
diff --git a/llvm/test/CodeGen/AArch64/neon-extadd-extract.ll b/llvm/test/CodeGen/AArch64/neon-extadd-extract.ll
index 5753798e87512..b35511dd4ab69 100644
--- a/llvm/test/CodeGen/AArch64/neon-extadd-extract.ll
+++ b/llvm/test/CodeGen/AArch64/neon-extadd-extract.ll
@@ -786,7 +786,7 @@ define <2 x i8> @extract_scalable_vec() vscale_range(1,16) "target-features"="+s
; CHECK-GI-LABEL: extract_scalable_vec:
; CHECK-GI: // %bb.0: // %entry
; CHECK-GI-NEXT: mov x8, xzr
-; CHECK-GI-NEXT: mov x9, #1 // =0x1
+; CHECK-GI-NEXT: mov w9, #1 // =0x1
; CHECK-GI-NEXT: ld1 { v0.b }[0], [x8]
; CHECK-GI-NEXT: ldr b1, [x9]
; CHECK-GI-NEXT: adrp x8, .LCPI36_0
>From b73902fd4669a5bdfc49e4ef2bba3f7d6d454cd5 Mon Sep 17 00:00:00 2001
From: Ryan Cowan <ryan.cowan at arm.com>
Date: Mon, 2 Feb 2026 14:45:23 +0000
Subject: [PATCH 5/5] Respond to review comments
---
.../AArch64/GISel/AArch64GlobalISelUtils.cpp | 2 +-
.../GISel/AArch64InstructionSelector.cpp | 12 ++++++------
.../AArch64/GISel/AArch64RegisterBankInfo.cpp | 7 ++++---
.../GlobalISel/preselect-process-phis.mir | 2 +-
.../AArch64/GlobalISel/select-constant.mir | 2 +-
.../CodeGen/AArch64/GlobalISel/select-dup.mir | 2 +-
.../CodeGen/AArch64/literal_pools_float.ll | 18 +++++++++++++-----
7 files changed, 27 insertions(+), 18 deletions(-)
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64GlobalISelUtils.cpp b/llvm/lib/Target/AArch64/GISel/AArch64GlobalISelUtils.cpp
index baf98ca8e4e3c..74cb5e9bb0729 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64GlobalISelUtils.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64GlobalISelUtils.cpp
@@ -24,7 +24,7 @@ AArch64GISelUtils::getAArch64VectorSplat(const MachineInstr &MI,
return std::nullopt;
Register Src = MI.getOperand(1).getReg();
if (auto ValAndVReg = getAnyConstantVRegValWithLookThrough(
- MI.getOperand(1).getReg(), MRI, true, true))
+ Src, MRI, /*LookThroughInstrs=*/true, /*LookThroughAnyExt=*/true))
return RegOrConstant(ValAndVReg->Value.getSExtValue());
return RegOrConstant(Src);
}
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
index b460eaa8a3772..0fc64608631cd 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
@@ -2362,8 +2362,8 @@ bool AArch64InstructionSelector::earlySelect(MachineInstr &I) {
// Before selecting a DUP instruction, check if it is better selected as a
// MOV or load from a constant pool.
Register Src = I.getOperand(1).getReg();
- auto ValAndVReg =
- getAnyConstantVRegValWithLookThrough(Src, MRI, true, true);
+ auto ValAndVReg = getAnyConstantVRegValWithLookThrough(
+ Src, MRI, /*LookThroughInstrs=*/true, /*LookThroughAnyExt=*/true);
if (!ValAndVReg)
return false;
LLVMContext &Ctx = MF.getFunction().getContext();
@@ -2680,8 +2680,7 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
return constrainSelectedInstRegOperands(*MovAddr, TII, TRI, RBI);
}
- case TargetOpcode::G_FCONSTANT:
- case TargetOpcode::G_CONSTANT: {
+ case TargetOpcode::G_FCONSTANT: {
const bool isFP = Opcode == TargetOpcode::G_FCONSTANT;
const Register DefReg = I.getOperand(0).getReg();
@@ -5743,8 +5742,9 @@ bool AArch64InstructionSelector::tryOptConstantBuildVec(
SmallVector<Constant *, 16> Csts;
for (unsigned Idx = 1; Idx < I.getNumOperands(); ++Idx) {
Register OpReg = I.getOperand(Idx).getReg();
- if (auto AnyConst =
- getAnyConstantVRegValWithLookThrough(OpReg, MRI, true, true)) {
+ if (auto AnyConst = getAnyConstantVRegValWithLookThrough(
+ OpReg, MRI, /*LookThroughInstrs=*/true,
+ /*LookThroughAnyExt=*/true)) {
MachineInstr *DefMI = MRI.getVRegDef(AnyConst->VReg);
if (DefMI->getOpcode() == TargetOpcode::G_CONSTANT) {
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
index 6cb645bc0a81b..cbaf6cb964203 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "AArch64RegisterBankInfo.h"
+#include "AArch64ISelLowering.h"
#include "AArch64RegisterInfo.h"
#include "AArch64Subtarget.h"
#include "MCTargetDesc/AArch64MCTargetDesc.h"
@@ -374,7 +375,7 @@ static bool isLegalFPImm(const MachineInstr &MI, const MachineRegisterInfo &MRI,
EVT VT = EVT::getFloatingPointVT(Bits);
bool OptForSize = MI.getMF()->getFunction().hasOptSize() ||
MI.getMF()->getFunction().hasMinSize();
- const TargetLowering *TLI = STI.getTargetLowering();
+ const AArch64TargetLowering *TLI = STI.getTargetLowering();
return TLI->isFPImmLegal(MI.getOperand(1).getFPImm()->getValueAPF(), VT,
OptForSize);
}
@@ -931,8 +932,8 @@ AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
break;
}
case TargetOpcode::G_FCONSTANT: {
- if (!isLegalFPImm(MI, MRI, STI) &&
- MRI.getType(MI.getOperand(0).getReg()).getScalarSizeInBits() != 128) {
+ LLT ImmTy = MRI.getType(MI.getOperand(0).getReg());
+ if (ImmTy.getScalarSizeInBits() != 128 && !isLegalFPImm(MI, MRI, STI)) {
// Materialize in GPR and rely on later bank copies for FP uses.
MappingID = CustomMappingID;
OpRegBankIdx = {PMI_FirstGPR};
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/preselect-process-phis.mir b/llvm/test/CodeGen/AArch64/GlobalISel/preselect-process-phis.mir
index b8a9209caa863..77d2010dcb030 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/preselect-process-phis.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/preselect-process-phis.mir
@@ -1,5 +1,5 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
-# RUN: llc -verify-machineinstrs -mtriple aarch64--- --run-pass=regbankselect --run-pass=instruction-select -global-isel-abort=1 %s -o - | FileCheck %s
+# RUN: llc -verify-machineinstrs -mtriple aarch64--- --run-pass=regbankselect,instruction-select -global-isel-abort=1 %s -o - | FileCheck %s
---
name: test_loop_phi_fpr_to_gpr
alignment: 4
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-constant.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-constant.mir
index 601ee70bd3e3d..41846ce172eac 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/select-constant.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-constant.mir
@@ -1,5 +1,5 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
-# RUN: llc -mtriple=aarch64-- -run-pass=regbankselect -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s
+# RUN: llc -mtriple=aarch64-- -run-pass=regbankselect,instruction-select -verify-machineinstrs %s -o - | FileCheck %s
--- |
target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-dup.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-dup.mir
index c5bea027403a3..83c323bcc51ea 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/select-dup.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-dup.mir
@@ -1,5 +1,5 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
-# RUN: llc -mtriple=aarch64 -run-pass=regbankselect -run-pass=instruction-select -verify-machineinstrs %s -o - | FileCheck %s
+# RUN: llc -mtriple=aarch64 -run-pass=regbankselect,instruction-select -verify-machineinstrs %s -o - | FileCheck %s
#
# GPR variants should not use INSERT_SUBREG. FPR variants (DUP<ty>lane) should.
diff --git a/llvm/test/CodeGen/AArch64/literal_pools_float.ll b/llvm/test/CodeGen/AArch64/literal_pools_float.ll
index 4debc8c87d57e..bf59223c6de8d 100644
--- a/llvm/test/CodeGen/AArch64/literal_pools_float.ll
+++ b/llvm/test/CodeGen/AArch64/literal_pools_float.ll
@@ -99,19 +99,26 @@ define dso_local float @float_ret_optnone() optnone noinline {
define dso_local double @double_ret_optnone() optnone noinline {
; CHECK-LABEL: double_ret_optnone:
; CHECK: // %bb.0:
-; CHECK-NEXT: adrp x8, .LCPI2_0
-; CHECK-NEXT: ldr d0, [x8, :lo12:.LCPI2_0]
+; CHECK-NEXT: mov x8, #-7378697629483820647 // =0x9999999999999999
+; CHECK-NEXT: movk x8, #39322
+; CHECK-NEXT: movk x8, #16313, lsl #48
+; CHECK-NEXT: fmov d0, x8
; CHECK-NEXT: ret
;
; CHECK-LARGE-LABEL: double_ret_optnone:
; CHECK-LARGE: // %bb.0:
-; CHECK-LARGE-NEXT: adrp x8, .LCPI2_0
-; CHECK-LARGE-NEXT: ldr d0, [x8, :lo12:.LCPI2_0]
+; CHECK-LARGE-NEXT: mov x8, #-7378697629483820647 // =0x9999999999999999
+; CHECK-LARGE-NEXT: movk x8, #39322
+; CHECK-LARGE-NEXT: movk x8, #16313, lsl #48
+; CHECK-LARGE-NEXT: fmov d0, x8
; CHECK-LARGE-NEXT: ret
;
; CHECK-TINY-LABEL: double_ret_optnone:
; CHECK-TINY: // %bb.0:
-; CHECK-TINY-NEXT: ldr d0, .LCPI2_0
+; CHECK-TINY-NEXT: mov x8, #-7378697629483820647 // =0x9999999999999999
+; CHECK-TINY-NEXT: movk x8, #39322
+; CHECK-TINY-NEXT: movk x8, #16313, lsl #48
+; CHECK-TINY-NEXT: fmov d0, x8
; CHECK-TINY-NEXT: ret
;
; CHECK-NOFP-LABEL: double_ret_optnone:
@@ -136,3 +143,4 @@ define dso_local double @double_ret_optnone() optnone noinline {
; CHECK-NOFP-TINY-NEXT: ret
ret double 0.1
}
+
More information about the llvm-commits
mailing list