Index: llvm/lib/Target/AArch64/AArch64InstrFormats.td =================================================================== --- llvm/lib/Target/AArch64/AArch64InstrFormats.td +++ llvm/lib/Target/AArch64/AArch64InstrFormats.td @@ -1178,6 +1178,13 @@ return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); }]>; +def fpimm32SimdXForm : SDNodeXFormgetValueAPF(); + const APInt ImmInt = FPVal.bitcastToAPInt(); + uint32_t enc = ImmInt.getZExtValue() >> 24; + return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); + }]>; + def fpimm64XForm : SDNodeXFormgetValueAPF(); uint32_t enc = AArch64_AM::getFP64Imm(InVal); @@ -1199,6 +1206,16 @@ let ParserMatchClass = FPImmOperand; let PrintMethod = "printFPImmOperand"; } + +def fpimm32Simd : Operand, + FPImmLeaf { + let ParserMatchClass = FPImmOperand; + let PrintMethod = "printFPImmOperand"; +} + def fpimm64 : Operand, FPImmLeaf; +// Using the MOVI to materialize fp constants. +def MOVIv2s_ns : BaseSIMDModifiedImmVectorShift<1, 1, 0b10, V128, "movi", ".2s", + [(set (v4f32 V128:$Rd), + (AArch64movi_shift imm0_255:$imm8, (i32 imm:$shift)))]>; +def : Pat<(f32 fpimm32Simd:$in), + (EXTRACT_SUBREG (MOVIv2s_ns (fpimm32SimdXForm f32:$in), (i32 24)), + ssub)>; // Deal with the various forms of (ELF) large addressing with MOVZ/MOVK // sequences. Index: llvm/test/Transforms/LoopVectorize/AArch64/remat-const-float-simd.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/LoopVectorize/AArch64/remat-const-float-simd.ll @@ -0,0 +1,28 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=aarch64-none-linux-gnu -verify-machineinstrs | FileCheck %s + +; Check that float(0x7fffffff) can be rematerialized with simd instruction +target triple = "aarch64-unknown-linux-gnu" + +; float foo(void) { return float(0x7fffffff); } +define float @foo() { +; CHECK-LABEL: foo: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: movi v0.2s, #79, lsl #24 +; CHECK-NEXT: // kill: def $s0 killed $s0 killed $q0 +; CHECK-NEXT: ret +entry: + ret float 0x41E0000000000000 +} + +; float foo2(float p) { return p + float(0x7fffffff); } +define float @foo2(float %f) { +; CHECK-LABEL: foo2: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: movi v1.2s, #79, lsl #24 +; CHECK-NEXT: fadd s0, s0, s1 +; CHECK-NEXT: ret +entry: + %p = fadd float %f, 0x41E0000000000000 + ret float %p +}