Index: llvm/include/llvm/Support/TargetOpcodes.def =================================================================== --- llvm/include/llvm/Support/TargetOpcodes.def +++ llvm/include/llvm/Support/TargetOpcodes.def @@ -493,6 +493,9 @@ /// Generic FP exponentiation. HANDLE_TARGET_OPCODE(G_FPOW) +/// Generic FP exponentiation, with an integer exponent. +HANDLE_TARGET_OPCODE(G_FPOWI) + /// Generic base-e exponential of a value. HANDLE_TARGET_OPCODE(G_FEXP) Index: llvm/include/llvm/Target/GenericOpcodes.td =================================================================== --- llvm/include/llvm/Target/GenericOpcodes.td +++ llvm/include/llvm/Target/GenericOpcodes.td @@ -732,6 +732,13 @@ let hasSideEffects = 0; } +// Floating point exponentiation, with an integer power. +def G_FPOWI : GenericInstruction { + let OutOperandList = (outs type0:$dst); + let InOperandList = (ins type0:$src0, type1:$src1); + let hasSideEffects = 0; +} + // Floating point base-e exponential of a value. def G_FEXP : GenericInstruction { let OutOperandList = (outs type0:$dst); Index: llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp =================================================================== --- llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -1264,6 +1264,8 @@ return TargetOpcode::G_FNEARBYINT; case Intrinsic::pow: return TargetOpcode::G_FPOW; + case Intrinsic::powi: + return TargetOpcode::G_FPOWI; case Intrinsic::rint: return TargetOpcode::G_FRINT; case Intrinsic::round: Index: llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll =================================================================== --- llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll +++ llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll @@ -1266,6 +1266,17 @@ ret float %res } +declare float @llvm.powi.f32(float, i32) +define float @test_powi_intrin(float %l, i32 %r) { +; CHECK-LABEL: name: test_powi_intrin +; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $s0 +; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w0 +; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FPOWI [[LHS]], [[RHS]] +; CHECK: $s0 = COPY [[RES]] + %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.powi.f32(float %l, i32 %r) + ret float %res +} + declare float @llvm.fma.f32(float, float, float) define float @test_fma_intrin(float %a, float %b, float %c) { ; CHECK-LABEL: name: test_fma_intrin Index: llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir =================================================================== --- llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir +++ llvm/test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir @@ -366,6 +366,9 @@ # DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}} # DEBUG-NEXT: .. the first uncovered type index: 1, OK # DEBUG-NEXT: .. the first uncovered imm index: 0, OK +# DEBUG-NEXT: G_FPOWI (opcode {{[0-9]+}}): 2 type indices, 0 imm indices +# DEBUG-NEXT:.. type index coverage check SKIPPED: no rules defined +# DEBUG-NEXT:.. imm index coverage check SKIPPED: no rules defined # DEBUG-NEXT: G_FEXP (opcode {{[0-9]+}}): 1 type index, 0 imm indices # DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}} # DEBUG-NEXT: .. the first uncovered type index: 1, OK