diff --git a/llvm/include/llvm/CodeGen/BasicTTIImpl.h b/llvm/include/llvm/CodeGen/BasicTTIImpl.h index 46bb84b4fec4..596db3923921 100644 --- a/llvm/include/llvm/CodeGen/BasicTTIImpl.h +++ b/llvm/include/llvm/CodeGen/BasicTTIImpl.h @@ -2258,6 +2258,12 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase { case Intrinsic::abs: ISD = ISD::ABS; break; + case Intrinsic::fshl: + ISD = ISD::FSHL; + break; + case Intrinsic::fshr: + ISD = ISD::FSHR; + break; case Intrinsic::smax: ISD = ISD::SMAX; break; @@ -2547,6 +2553,29 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase { {TTI::OK_UniformConstantValue, TTI::OP_None}); return Cost; } + case Intrinsic::fshl: + case Intrinsic::fshr: { + // fshl: (X << (Z % BW)) | (Y >> (BW - (Z % BW))) + // fshr: (X << (BW - (Z % BW))) | (Y >> (Z % BW)) + Type *CondTy = RetTy->getWithNewBitWidth(1); + InstructionCost Cost = 0; + Cost += + thisT()->getArithmeticInstrCost(BinaryOperator::Or, RetTy, CostKind); + Cost += + thisT()->getArithmeticInstrCost(BinaryOperator::Sub, RetTy, CostKind); + Cost += + thisT()->getArithmeticInstrCost(BinaryOperator::Shl, RetTy, CostKind); + Cost += thisT()->getArithmeticInstrCost(BinaryOperator::LShr, RetTy, + CostKind); + Cost += thisT()->getArithmeticInstrCost(BinaryOperator::URem, RetTy, + CostKind); + // Shift-by-zero handling. + Cost += thisT()->getCmpSelInstrCost(BinaryOperator::ICmp, RetTy, CondTy, + CmpInst::ICMP_EQ, CostKind); + Cost += thisT()->getCmpSelInstrCost(BinaryOperator::Select, RetTy, CondTy, + CmpInst::ICMP_EQ, CostKind); + return Cost; + } case Intrinsic::fptosi_sat: case Intrinsic::fptoui_sat: { if (Tys.empty()) diff --git a/llvm/test/Analysis/CostModel/AArch64/sve-intrinsics.ll b/llvm/test/Analysis/CostModel/AArch64/sve-intrinsics.ll index 3e5de313c3ca..696dec91d93d 100644 --- a/llvm/test/Analysis/CostModel/AArch64/sve-intrinsics.ll +++ b/llvm/test/Analysis/CostModel/AArch64/sve-intrinsics.ll @@ -1025,10 +1025,10 @@ define void @fshr() #0 { ; CHECK-VSCALE-2-NEXT: Cost Model: Found an estimated cost of 0 for instruction: ret void ; ; TYPE_BASED_ONLY-LABEL: 'fshr' -; TYPE_BASED_ONLY-NEXT: Cost Model: Invalid cost for instruction: %1 = call @llvm.fshr.nxv16i8( undef, undef, undef) -; TYPE_BASED_ONLY-NEXT: Cost Model: Invalid cost for instruction: %2 = call @llvm.fshr.nxv8i16( undef, undef, undef) -; TYPE_BASED_ONLY-NEXT: Cost Model: Invalid cost for instruction: %3 = call @llvm.fshr.nxv4i32( undef, undef, undef) -; TYPE_BASED_ONLY-NEXT: Cost Model: Invalid cost for instruction: %4 = call @llvm.fshr.nxv2i64( undef, undef, undef) +; TYPE_BASED_ONLY-NEXT: Cost Model: Found an estimated cost of 24 for instruction: %1 = call @llvm.fshr.nxv16i8( undef, undef, undef) +; TYPE_BASED_ONLY-NEXT: Cost Model: Found an estimated cost of 16 for instruction: %2 = call @llvm.fshr.nxv8i16( undef, undef, undef) +; TYPE_BASED_ONLY-NEXT: Cost Model: Found an estimated cost of 10 for instruction: %3 = call @llvm.fshr.nxv4i32( undef, undef, undef) +; TYPE_BASED_ONLY-NEXT: Cost Model: Found an estimated cost of 10 for instruction: %4 = call @llvm.fshr.nxv2i64( undef, undef, undef) ; TYPE_BASED_ONLY-NEXT: Cost Model: Found an estimated cost of 0 for instruction: ret void ; call @llvm.fshr.nxv16i8( undef, undef, undef) @@ -1054,10 +1054,10 @@ define void @fshl() #0 { ; CHECK-VSCALE-2-NEXT: Cost Model: Found an estimated cost of 0 for instruction: ret void ; ; TYPE_BASED_ONLY-LABEL: 'fshl' -; TYPE_BASED_ONLY-NEXT: Cost Model: Invalid cost for instruction: %1 = call @llvm.fshl.nxv16i8( undef, undef, undef) -; TYPE_BASED_ONLY-NEXT: Cost Model: Invalid cost for instruction: %2 = call @llvm.fshl.nxv8i16( undef, undef, undef) -; TYPE_BASED_ONLY-NEXT: Cost Model: Invalid cost for instruction: %3 = call @llvm.fshl.nxv4i32( undef, undef, undef) -; TYPE_BASED_ONLY-NEXT: Cost Model: Invalid cost for instruction: %4 = call @llvm.fshl.nxv2i64( undef, undef, undef) +; TYPE_BASED_ONLY-NEXT: Cost Model: Found an estimated cost of 24 for instruction: %1 = call @llvm.fshl.nxv16i8( undef, undef, undef) +; TYPE_BASED_ONLY-NEXT: Cost Model: Found an estimated cost of 16 for instruction: %2 = call @llvm.fshl.nxv8i16( undef, undef, undef) +; TYPE_BASED_ONLY-NEXT: Cost Model: Found an estimated cost of 10 for instruction: %3 = call @llvm.fshl.nxv4i32( undef, undef, undef) +; TYPE_BASED_ONLY-NEXT: Cost Model: Found an estimated cost of 10 for instruction: %4 = call @llvm.fshl.nxv2i64( undef, undef, undef) ; TYPE_BASED_ONLY-NEXT: Cost Model: Found an estimated cost of 0 for instruction: ret void ; call @llvm.fshl.nxv16i8( undef, undef, undef) diff --git a/llvm/test/Analysis/CostModel/RISCV/vp-intrinsics.ll b/llvm/test/Analysis/CostModel/RISCV/vp-intrinsics.ll index 5126a6a0a3cb..0245a0f7ee6c 100644 --- a/llvm/test/Analysis/CostModel/RISCV/vp-intrinsics.ll +++ b/llvm/test/Analysis/CostModel/RISCV/vp-intrinsics.ll @@ -38,7 +38,7 @@ define void @fshr( %a, %b, @llvm.fshr.nxv1i32( %a, %b, %c) +; TYPEBASED-NEXT: Cost Model: Found an estimated cost of 7 for instruction: %1 = call @llvm.fshr.nxv1i32( %a, %b, %c) ; TYPEBASED-NEXT: Cost Model: Found an estimated cost of 0 for instruction: ret void ; call @llvm.fshr.nxv4i32( %a, %b, %c) @@ -51,7 +51,7 @@ define void @fshl( %a, %b, @llvm.fshl.nxv1i32( %a, %b, %c) +; TYPEBASED-NEXT: Cost Model: Found an estimated cost of 7 for instruction: %1 = call @llvm.fshl.nxv1i32( %a, %b, %c) ; TYPEBASED-NEXT: Cost Model: Found an estimated cost of 0 for instruction: ret void ; call @llvm.fshl.nxv4i32( %a, %b, %c)