diff --git a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp --- a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp @@ -253,6 +253,13 @@ return LT.first * Instrs; break; } + case Intrinsic::bitreverse: { + static const auto ValidBitTys = {MVT::v8i16, MVT::v2i32, MVT::v4i32}; + auto LT = TLI->getTypeLegalizationCost(DL, RetTy); + if (any_of(ValidBitTys, [<](MVT M) { return M == LT.second; })) + return LT.first; + break; + } case Intrinsic::abs: { static const auto ValidAbsTys = {MVT::v8i8, MVT::v16i8, MVT::v4i16, MVT::v8i16, MVT::v2i32, MVT::v4i32, diff --git a/llvm/test/Analysis/CostModel/AArch64/bitreverse-cost-model.ll b/llvm/test/Analysis/CostModel/AArch64/bitreverse-cost-model.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Analysis/CostModel/AArch64/bitreverse-cost-model.ll @@ -0,0 +1,134 @@ +; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py +; RUN: opt -cost-model -analyze -cost-kind=code-size -mtriple=aarch64-none-eabi < %s | FileCheck %s --check-prefix=SIZE + +declare i8 @llvm.bitreverse.i8(i8) readnone + +define i8 @cost8(i8 %a) { +; SIZE-LABEL: 'cost8' +; SIZE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %b = call i8 @llvm.bitreverse.i8(i8 %a) +; SIZE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i8 %b +; + %b = call i8 @llvm.bitreverse.i8(i8 %a) + ret i8 %b +} + +declare i16 @llvm.bitreverse.i16(i16) readnone + +define i16 @cost16(i16 %a) { +; SIZE-LABEL: 'cost16' +; SIZE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %b = call i16 @llvm.bitreverse.i16(i16 %a) +; SIZE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i16 %b +; + %b = call i16 @llvm.bitreverse.i16(i16 %a) + ret i16 %b +} + +declare i32 @llvm.bitreverse.i32(i32) readnone + +define i32 @cost32(i32 %a) { +; SIZE-LABEL: 'cost32' +; SIZE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %b = call i32 @llvm.bitreverse.i32(i32 %a) +; SIZE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i32 %b +; + %b = call i32 @llvm.bitreverse.i32(i32 %a) + ret i32 %b +} + +declare i64 @llvm.bitreverse.i64(i64) readnone + +define i64 @cost64(i64 %a) { +; SIZE-LABEL: 'cost64' +; SIZE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %b = call i64 @llvm.bitreverse.i64(i64 %a) +; SIZE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret i64 %b +; + %b = call i64 @llvm.bitreverse.i64(i64 %a) + ret i64 %b +} + +declare <8 x i8> @llvm.bitreverse.v8i8(<8 x i8>) readnone + +define <8 x i8> @cost8x8(<8 x i8> %a) { +; SIZE-LABEL: 'cost8x8' +; SIZE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %b = call <8 x i8> @llvm.bitreverse.v8i8(<8 x i8> %a) +; SIZE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret <8 x i8> %b +; + %b = call <8 x i8> @llvm.bitreverse.v8i8(<8 x i8> %a) + ret <8 x i8> %b +} + +declare <16 x i8> @llvm.bitreverse.v16i8(<16 x i8>) readnone + +define <16 x i8> @cost16x8(<16 x i8> %a) { +; SIZE-LABEL: 'cost16x8' +; SIZE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %b = call <16 x i8> @llvm.bitreverse.v16i8(<16 x i8> %a) +; SIZE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret <16 x i8> %b +; + %b = call <16 x i8> @llvm.bitreverse.v16i8(<16 x i8> %a) + ret <16 x i8> %b +} + +declare <4 x i16> @llvm.bitreverse.v4i16(<4 x i16>) readnone + +define <4 x i16> @cost4x16(<4 x i16> %a) { +; SIZE-LABEL: 'cost4x16' +; SIZE-NEXT: Cost Model: Found an estimated cost of 22 for instruction: %b = call <4 x i16> @llvm.bitreverse.v4i16(<4 x i16> %a) +; SIZE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret <4 x i16> %b +; + %b = call <4 x i16> @llvm.bitreverse.v4i16(<4 x i16> %a) + ret <4 x i16> %b +} + +declare <8 x i16> @llvm.bitreverse.v8i16(<8 x i16>) readnone + +define <8 x i16> @cost8x16(<8 x i16> %a) { +; SIZE-LABEL: 'cost8x16' +; SIZE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %b = call <8 x i16> @llvm.bitreverse.v8i16(<8 x i16> %a) +; SIZE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret <8 x i16> %b +; + %b = call <8 x i16> @llvm.bitreverse.v8i16(<8 x i16> %a) + ret <8 x i16> %b +} + +declare <2 x i32> @llvm.bitreverse.v2i32(<2 x i32>) readnone + +define <2 x i32> @cost2x32(<2 x i32> %a) { +; SIZE-LABEL: 'cost2x32' +; SIZE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %b = call <2 x i32> @llvm.bitreverse.v2i32(<2 x i32> %a) +; SIZE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret <2 x i32> %b +; + %b = call <2 x i32> @llvm.bitreverse.v2i32(<2 x i32> %a) + ret <2 x i32> %b +} + +declare <4 x i32> @llvm.bitreverse.v4i32(<4 x i32>) readnone + +define <4 x i32> @cost4x32(<4 x i32> %a) { +; SIZE-LABEL: 'cost4x32' +; SIZE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %b = call <4 x i32> @llvm.bitreverse.v4i32(<4 x i32> %a) +; SIZE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret <4 x i32> %b +; + %b = call <4 x i32> @llvm.bitreverse.v4i32(<4 x i32> %a) + ret <4 x i32> %b +} + +declare <1 x i64> @llvm.bitreverse.v1i64(<1 x i64>) readnone + +define <1 x i64> @cost1x64(<1 x i64> %a) { +; SIZE-LABEL: 'cost1x64' +; SIZE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: %b = call <1 x i64> @llvm.bitreverse.v1i64(<1 x i64> %a) +; SIZE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret <1 x i64> %b +; + %b = call <1 x i64> @llvm.bitreverse.v1i64(<1 x i64> %a) + ret <1 x i64> %b +} + +declare <2 x i64> @llvm.bitreverse.v2i64(<2 x i64>) readnone + +define <2 x i64> @cost2x64(<2 x i64> %a) { +; SIZE-LABEL: 'cost2x64' +; SIZE-NEXT: Cost Model: Found an estimated cost of 8 for instruction: %b = call <2 x i64> @llvm.bitreverse.v2i64(<2 x i64> %a) +; SIZE-NEXT: Cost Model: Found an estimated cost of 1 for instruction: ret <2 x i64> %b +; + %b = call <2 x i64> @llvm.bitreverse.v2i64(<2 x i64> %a) + ret <2 x i64> %b +}