Skip to content

Commit fb512c9

Browse files
committed
[TTI][AArch64] Detect OperandInfo from scalable splats.
Pulled out of llvm#122236, this allows Splats contants to be recognized in by getOperandInfo, allowing "better" costs for instructions like divides by constants to be produced (which are expanded into mul+add+shift). Some of the costs are not very accurate yet, but the comparison of scalar vs fixed-with vs scalable for the same fiv can become more accurate, especially with patches like llvm#122236.
1 parent 7612dcc commit fb512c9

File tree

7 files changed

+109
-91
lines changed

7 files changed

+109
-91
lines changed

llvm/lib/Analysis/TargetTransformInfo.cpp

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -902,38 +902,39 @@ TargetTransformInfo::getOperandInfo(const Value *V) {
902902

903903
// Check for a splat of a constant or for a non uniform vector of constants
904904
// and check if the constant(s) are all powers of two.
905-
if (isa<ConstantVector>(V) || isa<ConstantDataVector>(V)) {
906-
OpInfo = OK_NonUniformConstantValue;
907-
if (Splat) {
905+
if (Splat) {
906+
// Check for a splat of a uniform value. This is not loop aware, so return
907+
// true only for the obviously uniform cases (argument, globalvalue)
908+
if (isa<Argument>(Splat) || isa<GlobalValue>(Splat)) {
909+
OpInfo = OK_UniformValue;
910+
} else if (isa<Constant>(Splat)) {
908911
OpInfo = OK_UniformConstantValue;
909912
if (auto *CI = dyn_cast<ConstantInt>(Splat)) {
910913
if (CI->getValue().isPowerOf2())
911914
OpProps = OP_PowerOf2;
912915
else if (CI->getValue().isNegatedPowerOf2())
913916
OpProps = OP_NegatedPowerOf2;
914917
}
915-
} else if (const auto *CDS = dyn_cast<ConstantDataSequential>(V)) {
916-
bool AllPow2 = true, AllNegPow2 = true;
917-
for (unsigned I = 0, E = CDS->getNumElements(); I != E; ++I) {
918-
if (auto *CI = dyn_cast<ConstantInt>(CDS->getElementAsConstant(I))) {
919-
AllPow2 &= CI->getValue().isPowerOf2();
920-
AllNegPow2 &= CI->getValue().isNegatedPowerOf2();
921-
if (AllPow2 || AllNegPow2)
922-
continue;
923-
}
924-
AllPow2 = AllNegPow2 = false;
925-
break;
918+
}
919+
} else if (const auto *CDS = dyn_cast<ConstantDataSequential>(V)) {
920+
OpInfo = OK_NonUniformConstantValue;
921+
bool AllPow2 = true, AllNegPow2 = true;
922+
for (unsigned I = 0, E = CDS->getNumElements(); I != E; ++I) {
923+
if (auto *CI = dyn_cast<ConstantInt>(CDS->getElementAsConstant(I))) {
924+
AllPow2 &= CI->getValue().isPowerOf2();
925+
AllNegPow2 &= CI->getValue().isNegatedPowerOf2();
926+
if (AllPow2 || AllNegPow2)
927+
continue;
926928
}
927-
OpProps = AllPow2 ? OP_PowerOf2 : OpProps;
928-
OpProps = AllNegPow2 ? OP_NegatedPowerOf2 : OpProps;
929+
AllPow2 = AllNegPow2 = false;
930+
break;
929931
}
932+
OpProps = AllPow2 ? OP_PowerOf2 : OpProps;
933+
OpProps = AllNegPow2 ? OP_NegatedPowerOf2 : OpProps;
934+
} else if (isa<ConstantVector>(V) || isa<ConstantDataVector>(V)) {
935+
OpInfo = OK_NonUniformConstantValue;
930936
}
931937

932-
// Check for a splat of a uniform value. This is not loop aware, so return
933-
// true only for the obviously uniform cases (argument, globalvalue)
934-
if (Splat && (isa<Argument>(Splat) || isa<GlobalValue>(Splat)))
935-
OpInfo = OK_UniformValue;
936-
937938
return {OpInfo, OpProps};
938939
}
939940

llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3522,7 +3522,8 @@ InstructionCost AArch64TTIImpl::getArithmeticInstrCost(
35223522
case ISD::UDIV: {
35233523
auto VT = TLI->getValueType(DL, Ty);
35243524
if (Op2Info.isConstant() && Op2Info.isUniform()) {
3525-
if (TLI->isOperationLegalOrCustom(ISD::MULHU, VT)) {
3525+
if (TLI->isOperationLegalOrCustom(ISD::MULHU, VT) &&
3526+
!VT.isScalableVector()) {
35263527
// Vector signed division by constant are expanded to the
35273528
// sequence MULHS + ADD/SUB + SRA + SRL + ADD, and unsigned division
35283529
// to MULHS + SUB + SRL + ADD + SRL.

llvm/test/Analysis/CostModel/AArch64/sve-div.ll

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -339,24 +339,24 @@ define void @sdiv_uniformconstpow2() {
339339
; CHECK-NEXT: Cost Model: Found an estimated cost of 99 for instruction: %V16i8 = sdiv <16 x i8> undef, splat (i8 16)
340340
; CHECK-NEXT: Cost Model: Found an estimated cost of 198 for instruction: %V32i8 = sdiv <32 x i8> undef, splat (i8 16)
341341
; CHECK-NEXT: Cost Model: Found an estimated cost of 396 for instruction: %V64i8 = sdiv <64 x i8> undef, splat (i8 16)
342-
; CHECK-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %NV2i64 = sdiv <vscale x 2 x i64> undef, splat (i64 16)
343-
; CHECK-NEXT: Cost Model: Found an estimated cost of 4 for instruction: %NV4i64 = sdiv <vscale x 4 x i64> undef, splat (i64 16)
344-
; CHECK-NEXT: Cost Model: Found an estimated cost of 8 for instruction: %NV8i64 = sdiv <vscale x 8 x i64> undef, splat (i64 16)
345-
; CHECK-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %NV2i32 = sdiv <vscale x 2 x i32> undef, splat (i32 16)
346-
; CHECK-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %NV4i32 = sdiv <vscale x 4 x i32> undef, splat (i32 16)
347-
; CHECK-NEXT: Cost Model: Found an estimated cost of 4 for instruction: %NV8i32 = sdiv <vscale x 8 x i32> undef, splat (i32 16)
348-
; CHECK-NEXT: Cost Model: Found an estimated cost of 8 for instruction: %NV16i32 = sdiv <vscale x 16 x i32> undef, splat (i32 16)
349-
; CHECK-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %NV2i16 = sdiv <vscale x 2 x i16> undef, splat (i16 16)
350-
; CHECK-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %NV4i16 = sdiv <vscale x 4 x i16> undef, splat (i16 16)
351-
; CHECK-NEXT: Cost Model: Found an estimated cost of 8 for instruction: %NV8i16 = sdiv <vscale x 8 x i16> undef, splat (i16 16)
352-
; CHECK-NEXT: Cost Model: Found an estimated cost of 16 for instruction: %NV16i16 = sdiv <vscale x 16 x i16> undef, splat (i16 16)
353-
; CHECK-NEXT: Cost Model: Found an estimated cost of 32 for instruction: %NV32i16 = sdiv <vscale x 32 x i16> undef, splat (i16 16)
354-
; CHECK-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %NV2i8 = sdiv <vscale x 2 x i8> undef, splat (i8 16)
355-
; CHECK-NEXT: Cost Model: Found an estimated cost of 2 for instruction: %NV4i8 = sdiv <vscale x 4 x i8> undef, splat (i8 16)
356-
; CHECK-NEXT: Cost Model: Found an estimated cost of 8 for instruction: %NV8i8 = sdiv <vscale x 8 x i8> undef, splat (i8 16)
357-
; CHECK-NEXT: Cost Model: Found an estimated cost of 16 for instruction: %NV16i8 = sdiv <vscale x 16 x i8> undef, splat (i8 16)
358-
; CHECK-NEXT: Cost Model: Found an estimated cost of 32 for instruction: %NV32i8 = sdiv <vscale x 32 x i8> undef, splat (i8 16)
359-
; CHECK-NEXT: Cost Model: Found an estimated cost of 64 for instruction: %NV64i8 = sdiv <vscale x 64 x i8> undef, splat (i8 16)
342+
; CHECK-NEXT: Cost Model: Found an estimated cost of 5 for instruction: %NV2i64 = sdiv <vscale x 2 x i64> undef, splat (i64 16)
343+
; CHECK-NEXT: Cost Model: Found an estimated cost of 10 for instruction: %NV4i64 = sdiv <vscale x 4 x i64> undef, splat (i64 16)
344+
; CHECK-NEXT: Cost Model: Found an estimated cost of 20 for instruction: %NV8i64 = sdiv <vscale x 8 x i64> undef, splat (i64 16)
345+
; CHECK-NEXT: Cost Model: Found an estimated cost of 5 for instruction: %NV2i32 = sdiv <vscale x 2 x i32> undef, splat (i32 16)
346+
; CHECK-NEXT: Cost Model: Found an estimated cost of 5 for instruction: %NV4i32 = sdiv <vscale x 4 x i32> undef, splat (i32 16)
347+
; CHECK-NEXT: Cost Model: Found an estimated cost of 10 for instruction: %NV8i32 = sdiv <vscale x 8 x i32> undef, splat (i32 16)
348+
; CHECK-NEXT: Cost Model: Found an estimated cost of 20 for instruction: %NV16i32 = sdiv <vscale x 16 x i32> undef, splat (i32 16)
349+
; CHECK-NEXT: Cost Model: Found an estimated cost of 5 for instruction: %NV2i16 = sdiv <vscale x 2 x i16> undef, splat (i16 16)
350+
; CHECK-NEXT: Cost Model: Found an estimated cost of 5 for instruction: %NV4i16 = sdiv <vscale x 4 x i16> undef, splat (i16 16)
351+
; CHECK-NEXT: Cost Model: Found an estimated cost of 5 for instruction: %NV8i16 = sdiv <vscale x 8 x i16> undef, splat (i16 16)
352+
; CHECK-NEXT: Cost Model: Found an estimated cost of 10 for instruction: %NV16i16 = sdiv <vscale x 16 x i16> undef, splat (i16 16)
353+
; CHECK-NEXT: Cost Model: Found an estimated cost of 20 for instruction: %NV32i16 = sdiv <vscale x 32 x i16> undef, splat (i16 16)
354+
; CHECK-NEXT: Cost Model: Found an estimated cost of 5 for instruction: %NV2i8 = sdiv <vscale x 2 x i8> undef, splat (i8 16)
355+
; CHECK-NEXT: Cost Model: Found an estimated cost of 5 for instruction: %NV4i8 = sdiv <vscale x 4 x i8> undef, splat (i8 16)
356+
; CHECK-NEXT: Cost Model: Found an estimated cost of 5 for instruction: %NV8i8 = sdiv <vscale x 8 x i8> undef, splat (i8 16)
357+
; CHECK-NEXT: Cost Model: Found an estimated cost of 5 for instruction: %NV16i8 = sdiv <vscale x 16 x i8> undef, splat (i8 16)
358+
; CHECK-NEXT: Cost Model: Found an estimated cost of 10 for instruction: %NV32i8 = sdiv <vscale x 32 x i8> undef, splat (i8 16)
359+
; CHECK-NEXT: Cost Model: Found an estimated cost of 20 for instruction: %NV64i8 = sdiv <vscale x 64 x i8> undef, splat (i8 16)
360360
; CHECK-NEXT: Cost Model: Found an estimated cost of 0 for instruction: ret void
361361
;
362362
%V2i64 = sdiv <2 x i64> undef, splat (i64 16)

llvm/test/Analysis/CostModel/AArch64/sve-intrinsics.ll

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,17 +1011,17 @@ define void @get_lane_mask() #0 {
10111011

10121012
define void @fshr() #0 {
10131013
; CHECK-VSCALE-1-LABEL: 'fshr'
1014-
; CHECK-VSCALE-1-NEXT: Cost Model: Found an estimated cost of 13 for instruction: %1 = call <vscale x 16 x i8> @llvm.fshr.nxv16i8(<vscale x 16 x i8> undef, <vscale x 16 x i8> undef, <vscale x 16 x i8> undef)
1015-
; CHECK-VSCALE-1-NEXT: Cost Model: Found an estimated cost of 13 for instruction: %2 = call <vscale x 8 x i16> @llvm.fshr.nxv8i16(<vscale x 8 x i16> undef, <vscale x 8 x i16> undef, <vscale x 8 x i16> undef)
1016-
; CHECK-VSCALE-1-NEXT: Cost Model: Found an estimated cost of 13 for instruction: %3 = call <vscale x 4 x i32> @llvm.fshr.nxv4i32(<vscale x 4 x i32> undef, <vscale x 4 x i32> undef, <vscale x 4 x i32> undef)
1017-
; CHECK-VSCALE-1-NEXT: Cost Model: Found an estimated cost of 13 for instruction: %4 = call <vscale x 2 x i64> @llvm.fshr.nxv2i64(<vscale x 2 x i64> undef, <vscale x 2 x i64> undef, <vscale x 2 x i64> undef)
1014+
; CHECK-VSCALE-1-NEXT: Cost Model: Found an estimated cost of 22 for instruction: %1 = call <vscale x 16 x i8> @llvm.fshr.nxv16i8(<vscale x 16 x i8> undef, <vscale x 16 x i8> undef, <vscale x 16 x i8> undef)
1015+
; CHECK-VSCALE-1-NEXT: Cost Model: Found an estimated cost of 14 for instruction: %2 = call <vscale x 8 x i16> @llvm.fshr.nxv8i16(<vscale x 8 x i16> undef, <vscale x 8 x i16> undef, <vscale x 8 x i16> undef)
1016+
; CHECK-VSCALE-1-NEXT: Cost Model: Found an estimated cost of 8 for instruction: %3 = call <vscale x 4 x i32> @llvm.fshr.nxv4i32(<vscale x 4 x i32> undef, <vscale x 4 x i32> undef, <vscale x 4 x i32> undef)
1017+
; CHECK-VSCALE-1-NEXT: Cost Model: Found an estimated cost of 8 for instruction: %4 = call <vscale x 2 x i64> @llvm.fshr.nxv2i64(<vscale x 2 x i64> undef, <vscale x 2 x i64> undef, <vscale x 2 x i64> undef)
10181018
; CHECK-VSCALE-1-NEXT: Cost Model: Found an estimated cost of 0 for instruction: ret void
10191019
;
10201020
; CHECK-VSCALE-2-LABEL: 'fshr'
1021-
; CHECK-VSCALE-2-NEXT: Cost Model: Found an estimated cost of 13 for instruction: %1 = call <vscale x 16 x i8> @llvm.fshr.nxv16i8(<vscale x 16 x i8> undef, <vscale x 16 x i8> undef, <vscale x 16 x i8> undef)
1022-
; CHECK-VSCALE-2-NEXT: Cost Model: Found an estimated cost of 13 for instruction: %2 = call <vscale x 8 x i16> @llvm.fshr.nxv8i16(<vscale x 8 x i16> undef, <vscale x 8 x i16> undef, <vscale x 8 x i16> undef)
1023-
; CHECK-VSCALE-2-NEXT: Cost Model: Found an estimated cost of 13 for instruction: %3 = call <vscale x 4 x i32> @llvm.fshr.nxv4i32(<vscale x 4 x i32> undef, <vscale x 4 x i32> undef, <vscale x 4 x i32> undef)
1024-
; CHECK-VSCALE-2-NEXT: Cost Model: Found an estimated cost of 13 for instruction: %4 = call <vscale x 2 x i64> @llvm.fshr.nxv2i64(<vscale x 2 x i64> undef, <vscale x 2 x i64> undef, <vscale x 2 x i64> undef)
1021+
; CHECK-VSCALE-2-NEXT: Cost Model: Found an estimated cost of 22 for instruction: %1 = call <vscale x 16 x i8> @llvm.fshr.nxv16i8(<vscale x 16 x i8> undef, <vscale x 16 x i8> undef, <vscale x 16 x i8> undef)
1022+
; CHECK-VSCALE-2-NEXT: Cost Model: Found an estimated cost of 14 for instruction: %2 = call <vscale x 8 x i16> @llvm.fshr.nxv8i16(<vscale x 8 x i16> undef, <vscale x 8 x i16> undef, <vscale x 8 x i16> undef)
1023+
; CHECK-VSCALE-2-NEXT: Cost Model: Found an estimated cost of 8 for instruction: %3 = call <vscale x 4 x i32> @llvm.fshr.nxv4i32(<vscale x 4 x i32> undef, <vscale x 4 x i32> undef, <vscale x 4 x i32> undef)
1024+
; CHECK-VSCALE-2-NEXT: Cost Model: Found an estimated cost of 8 for instruction: %4 = call <vscale x 2 x i64> @llvm.fshr.nxv2i64(<vscale x 2 x i64> undef, <vscale x 2 x i64> undef, <vscale x 2 x i64> undef)
10251025
; CHECK-VSCALE-2-NEXT: Cost Model: Found an estimated cost of 0 for instruction: ret void
10261026
;
10271027
; TYPE_BASED_ONLY-LABEL: 'fshr'
@@ -1040,17 +1040,17 @@ define void @fshr() #0 {
10401040

10411041
define void @fshl() #0 {
10421042
; CHECK-VSCALE-1-LABEL: 'fshl'
1043-
; CHECK-VSCALE-1-NEXT: Cost Model: Found an estimated cost of 13 for instruction: %1 = call <vscale x 16 x i8> @llvm.fshl.nxv16i8(<vscale x 16 x i8> undef, <vscale x 16 x i8> undef, <vscale x 16 x i8> undef)
1044-
; CHECK-VSCALE-1-NEXT: Cost Model: Found an estimated cost of 13 for instruction: %2 = call <vscale x 8 x i16> @llvm.fshl.nxv8i16(<vscale x 8 x i16> undef, <vscale x 8 x i16> undef, <vscale x 8 x i16> undef)
1045-
; CHECK-VSCALE-1-NEXT: Cost Model: Found an estimated cost of 13 for instruction: %3 = call <vscale x 4 x i32> @llvm.fshl.nxv4i32(<vscale x 4 x i32> undef, <vscale x 4 x i32> undef, <vscale x 4 x i32> undef)
1046-
; CHECK-VSCALE-1-NEXT: Cost Model: Found an estimated cost of 13 for instruction: %4 = call <vscale x 2 x i64> @llvm.fshl.nxv2i64(<vscale x 2 x i64> undef, <vscale x 2 x i64> undef, <vscale x 2 x i64> undef)
1043+
; CHECK-VSCALE-1-NEXT: Cost Model: Found an estimated cost of 22 for instruction: %1 = call <vscale x 16 x i8> @llvm.fshl.nxv16i8(<vscale x 16 x i8> undef, <vscale x 16 x i8> undef, <vscale x 16 x i8> undef)
1044+
; CHECK-VSCALE-1-NEXT: Cost Model: Found an estimated cost of 14 for instruction: %2 = call <vscale x 8 x i16> @llvm.fshl.nxv8i16(<vscale x 8 x i16> undef, <vscale x 8 x i16> undef, <vscale x 8 x i16> undef)
1045+
; CHECK-VSCALE-1-NEXT: Cost Model: Found an estimated cost of 8 for instruction: %3 = call <vscale x 4 x i32> @llvm.fshl.nxv4i32(<vscale x 4 x i32> undef, <vscale x 4 x i32> undef, <vscale x 4 x i32> undef)
1046+
; CHECK-VSCALE-1-NEXT: Cost Model: Found an estimated cost of 8 for instruction: %4 = call <vscale x 2 x i64> @llvm.fshl.nxv2i64(<vscale x 2 x i64> undef, <vscale x 2 x i64> undef, <vscale x 2 x i64> undef)
10471047
; CHECK-VSCALE-1-NEXT: Cost Model: Found an estimated cost of 0 for instruction: ret void
10481048
;
10491049
; CHECK-VSCALE-2-LABEL: 'fshl'
1050-
; CHECK-VSCALE-2-NEXT: Cost Model: Found an estimated cost of 13 for instruction: %1 = call <vscale x 16 x i8> @llvm.fshl.nxv16i8(<vscale x 16 x i8> undef, <vscale x 16 x i8> undef, <vscale x 16 x i8> undef)
1051-
; CHECK-VSCALE-2-NEXT: Cost Model: Found an estimated cost of 13 for instruction: %2 = call <vscale x 8 x i16> @llvm.fshl.nxv8i16(<vscale x 8 x i16> undef, <vscale x 8 x i16> undef, <vscale x 8 x i16> undef)
1052-
; CHECK-VSCALE-2-NEXT: Cost Model: Found an estimated cost of 13 for instruction: %3 = call <vscale x 4 x i32> @llvm.fshl.nxv4i32(<vscale x 4 x i32> undef, <vscale x 4 x i32> undef, <vscale x 4 x i32> undef)
1053-
; CHECK-VSCALE-2-NEXT: Cost Model: Found an estimated cost of 13 for instruction: %4 = call <vscale x 2 x i64> @llvm.fshl.nxv2i64(<vscale x 2 x i64> undef, <vscale x 2 x i64> undef, <vscale x 2 x i64> undef)
1050+
; CHECK-VSCALE-2-NEXT: Cost Model: Found an estimated cost of 22 for instruction: %1 = call <vscale x 16 x i8> @llvm.fshl.nxv16i8(<vscale x 16 x i8> undef, <vscale x 16 x i8> undef, <vscale x 16 x i8> undef)
1051+
; CHECK-VSCALE-2-NEXT: Cost Model: Found an estimated cost of 14 for instruction: %2 = call <vscale x 8 x i16> @llvm.fshl.nxv8i16(<vscale x 8 x i16> undef, <vscale x 8 x i16> undef, <vscale x 8 x i16> undef)
1052+
; CHECK-VSCALE-2-NEXT: Cost Model: Found an estimated cost of 8 for instruction: %3 = call <vscale x 4 x i32> @llvm.fshl.nxv4i32(<vscale x 4 x i32> undef, <vscale x 4 x i32> undef, <vscale x 4 x i32> undef)
1053+
; CHECK-VSCALE-2-NEXT: Cost Model: Found an estimated cost of 8 for instruction: %4 = call <vscale x 2 x i64> @llvm.fshl.nxv2i64(<vscale x 2 x i64> undef, <vscale x 2 x i64> undef, <vscale x 2 x i64> undef)
10541054
; CHECK-VSCALE-2-NEXT: Cost Model: Found an estimated cost of 0 for instruction: ret void
10551055
;
10561056
; TYPE_BASED_ONLY-LABEL: 'fshl'

0 commit comments

Comments
 (0)