Skip to content

Commit 902b07f

Browse files
[LLVM][InstCombine][SVE] Improve isAllActivePredicate by looking through from.svbool. (#164446)
When a predicate is of the form "%a = sve.from.vsbool(%b)" we know all bits in %a come from %b and thus if %b is all true then %a must also be all true.
1 parent 4f4bee4 commit 902b07f

File tree

2 files changed

+50
-9
lines changed

2 files changed

+50
-9
lines changed

llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1577,18 +1577,26 @@ static SVEIntrinsicInfo constructSVEIntrinsicInfo(IntrinsicInst &II) {
15771577
}
15781578

15791579
static bool isAllActivePredicate(Value *Pred) {
1580-
// Look through convert.from.svbool(convert.to.svbool(...) chain.
15811580
Value *UncastedPred;
1581+
1582+
// Look through predicate casts that only remove lanes.
15821583
if (match(Pred, m_Intrinsic<Intrinsic::aarch64_sve_convert_from_svbool>(
1583-
m_Intrinsic<Intrinsic::aarch64_sve_convert_to_svbool>(
1584-
m_Value(UncastedPred)))))
1585-
// If the predicate has the same or less lanes than the uncasted
1586-
// predicate then we know the casting has no effect.
1587-
if (cast<ScalableVectorType>(Pred->getType())->getMinNumElements() <=
1588-
cast<ScalableVectorType>(UncastedPred->getType())->getMinNumElements())
1589-
Pred = UncastedPred;
1584+
m_Value(UncastedPred)))) {
1585+
auto *OrigPredTy = cast<ScalableVectorType>(Pred->getType());
1586+
Pred = UncastedPred;
1587+
1588+
if (match(Pred, m_Intrinsic<Intrinsic::aarch64_sve_convert_to_svbool>(
1589+
m_Value(UncastedPred))))
1590+
// If the predicate has the same or less lanes than the uncasted predicate
1591+
// then we know the casting has no effect.
1592+
if (OrigPredTy->getMinNumElements() <=
1593+
cast<ScalableVectorType>(UncastedPred->getType())
1594+
->getMinNumElements())
1595+
Pred = UncastedPred;
1596+
}
1597+
15901598
auto *C = dyn_cast<Constant>(Pred);
1591-
return (C && C->isAllOnesValue());
1599+
return C && C->isAllOnesValue();
15921600
}
15931601

15941602
// Simplify `V` by only considering the operations that affect active lanes.

llvm/test/Transforms/InstCombine/AArch64/sve-intrinsic-to-svbool-binops.ll

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,39 @@ define <vscale x 8 x i1> @try_combine_svbool_binop_orr(<vscale x 8 x i1> %a, <vs
124124
ret <vscale x 8 x i1> %t3
125125
}
126126

127+
; Verify predicate cast does not hinder "isAllActive" knowledge.
128+
define <vscale x 8 x half> @try_combine_svbool_binop_fadd(<vscale x 8 x half> %a, <vscale x 8 x half> %b) {
129+
; CHECK-LABEL: @try_combine_svbool_binop_fadd(
130+
; CHECK-NEXT: [[T2:%.*]] = fadd <vscale x 8 x half> [[A:%.*]], [[B:%.*]]
131+
; CHECK-NEXT: ret <vscale x 8 x half> [[T2]]
132+
;
133+
%t1 = tail call <vscale x 8 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv8i1(<vscale x 16 x i1> splat (i1 true))
134+
%t2 = tail call <vscale x 8 x half> @llvm.aarch64.sve.fadd.nxv8f16(<vscale x 8 x i1> %t1, <vscale x 8 x half> %a, <vscale x 8 x half> %b)
135+
ret <vscale x 8 x half> %t2
136+
}
137+
138+
; Verify predicate cast does not hinder "isAllActive" knowledge.
139+
define <vscale x 4 x float> @try_combine_svbool_binop_fmul(<vscale x 4 x float> %a, <vscale x 4 x float> %b) {
140+
; CHECK-LABEL: @try_combine_svbool_binop_fmul(
141+
; CHECK-NEXT: [[T2:%.*]] = fmul <vscale x 4 x float> [[A:%.*]], [[B:%.*]]
142+
; CHECK-NEXT: ret <vscale x 4 x float> [[T2]]
143+
;
144+
%t1 = tail call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> splat (i1 true))
145+
%t2 = tail call <vscale x 4 x float> @llvm.aarch64.sve.fmul.nxv4f32(<vscale x 4 x i1> %t1, <vscale x 4 x float> %a, <vscale x 4 x float> %b)
146+
ret <vscale x 4 x float> %t2
147+
}
148+
149+
; Verify predicate cast does not hinder "isAllActive" knowledge.
150+
define <vscale x 2 x double> @try_combine_svbool_binop_fsub(<vscale x 2 x double> %a, <vscale x 2 x double> %b) {
151+
; CHECK-LABEL: @try_combine_svbool_binop_fsub(
152+
; CHECK-NEXT: [[T2:%.*]] = fsub <vscale x 2 x double> [[A:%.*]], [[B:%.*]]
153+
; CHECK-NEXT: ret <vscale x 2 x double> [[T2]]
154+
;
155+
%t1 = tail call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> splat (i1 true))
156+
%t2 = tail call <vscale x 2 x double> @llvm.aarch64.sve.fsub.nxv2f64(<vscale x 2 x i1> %t1, <vscale x 2 x double> %a, <vscale x 2 x double> %b)
157+
ret <vscale x 2 x double> %t2
158+
}
159+
127160
declare <vscale x 16 x i1> @llvm.aarch64.sve.convert.to.svbool.nxv8i1(<vscale x 8 x i1>)
128161
declare <vscale x 16 x i1> @llvm.aarch64.sve.convert.to.svbool.nxv4i1(<vscale x 4 x i1>)
129162
declare <vscale x 16 x i1> @llvm.aarch64.sve.convert.to.svbool.nxv2i1(<vscale x 2 x i1>)

0 commit comments

Comments
 (0)