From: Jessica Paquette Date: Wed, 19 Dec 2018 19:01:36 +0000 (+0000) Subject: [GlobalISel][AArch64] Add support for @llvm.ceil X-Git-Tag: llvmorg-8.0.0-rc1~1640 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3560e93dc19622b1def6cbc13f11776e8d6fac3c;p=platform%2Fupstream%2Fllvm.git [GlobalISel][AArch64] Add support for @llvm.ceil This adds a G_FCEIL generic instruction and uses it in AArch64. This adds selection for floating point ceil where it has a supported, dedicated instruction. Other cases aren't handled here. It updates the relevant gisel tests and adds a select-ceil test. It also adds a check to arm64-vcvt.ll which ensures that we don't fall back when we run into one of the relevant cases. llvm-svn: 349664 --- diff --git a/llvm/include/llvm/Support/TargetOpcodes.def b/llvm/include/llvm/Support/TargetOpcodes.def index 3245276..3e8193a 100644 --- a/llvm/include/llvm/Support/TargetOpcodes.def +++ b/llvm/include/llvm/Support/TargetOpcodes.def @@ -518,6 +518,9 @@ HANDLE_TARGET_OPCODE(G_CTPOP) /// Generic byte swap. HANDLE_TARGET_OPCODE(G_BSWAP) +/// Floating point ceil. +HANDLE_TARGET_OPCODE(G_FCEIL) + /// Generic AddressSpaceCast. HANDLE_TARGET_OPCODE(G_ADDRSPACE_CAST) diff --git a/llvm/include/llvm/Target/GenericOpcodes.td b/llvm/include/llvm/Target/GenericOpcodes.td index 775221a..045fe252 100644 --- a/llvm/include/llvm/Target/GenericOpcodes.td +++ b/llvm/include/llvm/Target/GenericOpcodes.td @@ -547,6 +547,13 @@ def G_FLOG10 : GenericInstruction { let hasSideEffects = 0; } +// Floating point ceiling of a value. +def G_FCEIL : GenericInstruction { + let OutOperandList = (outs type0:$dst); + let InOperandList = (ins type0:$src1); + let hasSideEffects = 0; +} + //------------------------------------------------------------------------------ // Opcodes for LLVM Intrinsics //------------------------------------------------------------------------------ diff --git a/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td b/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td index af26375..31d2636 100644 --- a/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td +++ b/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td @@ -89,6 +89,7 @@ def : GINodeEquiv; def : GINodeEquiv; def : GINodeEquiv; def : GINodeEquiv; +def : GINodeEquiv; // Broadly speaking G_LOAD is equivalent to ISD::LOAD but there are some // complications that tablegen must take care of. For example, Predicates such diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp index 3331375..4feb624 100644 --- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -1040,6 +1040,11 @@ bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID, } case Intrinsic::invariant_end: return true; + case Intrinsic::ceil: + MIRBuilder.buildInstr(TargetOpcode::G_FCEIL) + .addDef(getOrCreateVReg(CI)) + .addUse(getOrCreateVReg(*CI.getArgOperand(0))); + return true; } return false; } diff --git a/llvm/lib/Target/AArch64/AArch64LegalizerInfo.cpp b/llvm/lib/Target/AArch64/AArch64LegalizerInfo.cpp index 5d63f0c..f0700ed 100644 --- a/llvm/lib/Target/AArch64/AArch64LegalizerInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64LegalizerInfo.cpp @@ -97,6 +97,10 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST) { getActionDefinitionsBuilder({G_FREM, G_FPOW}).libcallFor({s32, s64}); + // TODO: Handle s16. + getActionDefinitionsBuilder(G_FCEIL) + .legalFor({s32, s64, v2s32, v4s32, v2s64}); + getActionDefinitionsBuilder(G_INSERT) .unsupportedIf([=](const LegalityQuery &Query) { return Query.Types[0].getSizeInBits() <= Query.Types[1].getSizeInBits(); diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll index 74de033..48a5c84 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll +++ b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll @@ -2242,3 +2242,44 @@ define void @test_invariant_intrin() { call void @llvm.invariant.end.p0i8({}* %inv, i64 8, i8* %y) ret void } + +declare float @llvm.ceil.f32(float) +define float @test_ceil_f32(float %x) { + ; CHECK-LABEL: name: test_ceil_f32 + ; CHECK: %{{[0-9]+}}:_(s32) = G_FCEIL %{{[0-9]+}} + %y = call float @llvm.ceil.f32(float %x) + ret float %y +} + +declare double @llvm.ceil.f64(double) +define double @test_ceil_f64(double %x) { + ; CHECK-LABEL: name: test_ceil_f64 + ; CHECK: %{{[0-9]+}}:_(s64) = G_FCEIL %{{[0-9]+}} + %y = call double @llvm.ceil.f64(double %x) + ret double %y +} + +declare <2 x float> @llvm.ceil.v2f32(<2 x float>) +define <2 x float> @test_ceil_v2f32(<2 x float> %x) { + ; CHECK-LABEL: name: test_ceil_v2f32 + ; CHECK: %{{[0-9]+}}:_(<2 x s32>) = G_FCEIL %{{[0-9]+}} + %y = call <2 x float> @llvm.ceil.v2f32(<2 x float> %x) + ret <2 x float> %y +} + +declare <4 x float> @llvm.ceil.v4f32(<4 x float>) +define <4 x float> @test_ceil_v4f32(<4 x float> %x) { + ; CHECK-LABEL: name: test_ceil_v4f32 + ; CHECK: %{{[0-9]+}}:_(<4 x s32>) = G_FCEIL %{{[0-9]+}} + ; SELECT: %{{[0-9]+}}:fpr128 = FRINTPv4f32 %{{[0-9]+}} + %y = call <4 x float> @llvm.ceil.v4f32(<4 x float> %x) + ret <4 x float> %y +} + +declare <2 x double> @llvm.ceil.v2f64(<2 x double>) +define <2 x double> @test_ceil_v2f64(<2 x double> %x) { + ; CHECK-LABEL: name: test_ceil_v2f64 + ; CHECK: %{{[0-9]+}}:_(<2 x s64>) = G_FCEIL %{{[0-9]+}} + %y = call <2 x double> @llvm.ceil.v2f64(<2 x double> %x) + ret <2 x double> %y +} diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir b/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir index 0c75cd3..c18a2b8 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir @@ -329,6 +329,9 @@ # # DEBUG-NEXT: G_BSWAP (opcode {{[0-9]+}}): 1 type index # DEBUG: .. the first uncovered type index: 1, OK +# +# DEBUG-NEXT: G_FCEIL (opcode {{[0-9]+}}): 1 type index +# DEBUG: .. the first uncovered type index: 1, OK # CHECK-NOT: ill-defined diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-ceil.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-ceil.mir new file mode 100644 index 0000000..5d42a2c --- /dev/null +++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-ceil.mir @@ -0,0 +1,93 @@ +# RUN: llc -verify-machineinstrs -mtriple aarch64--- \ +# RUN: -run-pass=instruction-select -global-isel %s -o - | FileCheck %s +... +--- +name: ceil_float +legalized: true +regBankSelected: true +tracksRegLiveness: true +registers: + - { id: 0, class: fpr } + - { id: 1, class: fpr } +body: | + bb.0: + ; CHECK-LABEL: name: ceil_float + ; CHECK: %{{[0-9]+}}:fpr32 = FRINTPSr %{{[0-9]+}} + liveins: $s0 + %0:fpr(s32) = COPY $s0 + %1:fpr(s32) = G_FCEIL %0 + $s0 = COPY %1(s32) + +... +--- +name: ceil_double +legalized: true +regBankSelected: true +tracksRegLiveness: true +registers: + - { id: 0, class: fpr } + - { id: 1, class: fpr } +body: | + bb.0: + ; CHECK-LABEL: name: ceil_double + ; CHECK: %{{[0-9]+}}:fpr64 = FRINTPDr %{{[0-9]+}} + liveins: $d0 + %0:fpr(s64) = COPY $d0 + %1:fpr(s64) = G_FCEIL %0 + $d0 = COPY %1(s64) + +... +--- +name: ceil_v2f32 +legalized: true +regBankSelected: true +tracksRegLiveness: true +registers: + - { id: 0, class: fpr } + - { id: 1, class: fpr } +body: | + bb.0: + ; CHECK-LABEL: name: ceil_v2f32 + ; CHECK: %{{[0-9]+}}:fpr64 = FRINTPv2f32 %{{[0-9]+}} + liveins: $d0 + %0:fpr(<2 x s32>) = COPY $d0 + %1:fpr(<2 x s32>) = G_FCEIL %0 + $d0 = COPY %1(<2 x s32>) + +... +--- +name: ceil_v4f32 +legalized: true +regBankSelected: true +tracksRegLiveness: true +registers: + - { id: 0, class: fpr } + - { id: 1, class: fpr } +body: | + bb.0: + ; CHECK-LABEL: name: ceil_v4f32 + ; CHECK: %{{[0-9]+}}:fpr128 = FRINTPv4f32 %{{[0-9]+}} + liveins: $q0 + %0:fpr(<4 x s32>) = COPY $q0 + %1:fpr(<4 x s32>) = G_FCEIL %0 + $q0 = COPY %1(<4 x s32>) + +... +--- +name: ceil_v2f64 +legalized: true +regBankSelected: true +tracksRegLiveness: true +registers: + - { id: 0, class: fpr } + - { id: 1, class: fpr } +body: | + bb.0: + ; CHECK-LABEL: name: ceil_v2f64 + ; CHECK: %{{[0-9]+}}:fpr128 = FRINTPv2f64 %{{[0-9]+}} + liveins: $q0 + %0:fpr(<2 x s64>) = COPY $q0 + %1:fpr(<2 x s64>) = G_FCEIL %0 + $q0 = COPY %1(<2 x s64>) + +... diff --git a/llvm/test/CodeGen/AArch64/arm64-vcvt.ll b/llvm/test/CodeGen/AArch64/arm64-vcvt.ll index f7437bc..d236aea 100644 --- a/llvm/test/CodeGen/AArch64/arm64-vcvt.ll +++ b/llvm/test/CodeGen/AArch64/arm64-vcvt.ll @@ -1,4 +1,7 @@ ; RUN: llc < %s -mtriple=arm64-eabi -aarch64-neon-syntax=apple | FileCheck %s +; RUN: llc < %s -mtriple=arm64-eabi -pass-remarks-missed=gisel-* \ +; RUN: -aarch64-neon-syntax=apple -global-isel -global-isel-abort=2 2>&1 | \ +; RUN: FileCheck %s --check-prefixes=FALLBACK,CHECK define <2 x i32> @fcvtas_2s(<2 x float> %A) nounwind { ;CHECK-LABEL: fcvtas_2s: @@ -427,6 +430,7 @@ declare <2 x float> @llvm.aarch64.neon.frintn.v2f32(<2 x float>) nounwind readno declare <4 x float> @llvm.aarch64.neon.frintn.v4f32(<4 x float>) nounwind readnone declare <2 x double> @llvm.aarch64.neon.frintn.v2f64(<2 x double>) nounwind readnone +; FALLBACK-NOT: remark{{.*}}frintp_2s define <2 x float> @frintp_2s(<2 x float> %A) nounwind { ;CHECK-LABEL: frintp_2s: ;CHECK-NOT: ld1 @@ -436,6 +440,7 @@ define <2 x float> @frintp_2s(<2 x float> %A) nounwind { ret <2 x float> %tmp3 } +; FALLBACK-NOT: remark{{.*}}frintp_4s define <4 x float> @frintp_4s(<4 x float> %A) nounwind { ;CHECK-LABEL: frintp_4s: ;CHECK-NOT: ld1 @@ -445,6 +450,7 @@ define <4 x float> @frintp_4s(<4 x float> %A) nounwind { ret <4 x float> %tmp3 } +; FALLBACK-NOT: remark{{.*}}frintp_2d define <2 x double> @frintp_2d(<2 x double> %A) nounwind { ;CHECK-LABEL: frintp_2d: ;CHECK-NOT: ld1