Skip to content

Commit 9a5b0f3

Browse files
authored
Reapply "[InstCombine] Match scalable splats in m_ImmConstant (#132522)" (#134262)
This reapplies #132522. Previously casts of scalable m_ImmConstant splats weren't being folded by ConstantFoldCastOperand, triggering the "Constant-fold of ImmConstant should not fail" assertion. There are no changes to the code in this PR, instead we just needed #133207 to land first. A test has been added for the assertion in llvm/test/Transforms/InstSimplify/vec-icmp-of-cast.ll @icmp_ult_sext_scalable_splat_is_true. <hr/> #118806 fixed an infinite loop in FoldShiftByConstant that could occur when the shift amount was a ConstantExpr. However this meant that FoldShiftByConstant no longer kicked in for scalable vectors because scalable splats are represented by ConstantExprs. This fixes it by allowing scalable splats of non-ConstantExprs in m_ImmConstant, which also fixes a few other test cases where scalable splats were being missed. But I'm also hoping that UseConstantIntForScalableSplat will eventually remove the need for this. I noticed this when trying to reverse a combine on RISC-V in #132245, and saw that the resulting vector and scalar forms were different.
1 parent a54736a commit 9a5b0f3

File tree

6 files changed

+75
-14
lines changed

6 files changed

+75
-14
lines changed

llvm/include/llvm/IR/PatternMatch.h

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -858,18 +858,51 @@ inline bind_ty<const BasicBlock> m_BasicBlock(const BasicBlock *&V) {
858858
return V;
859859
}
860860

861+
// TODO: Remove once UseConstant{Int,FP}ForScalableSplat is enabled by default,
862+
// and use m_Unless(m_ConstantExpr).
863+
struct immconstant_ty {
864+
template <typename ITy> static bool isImmConstant(ITy *V) {
865+
if (auto *CV = dyn_cast<Constant>(V)) {
866+
if (!isa<ConstantExpr>(CV) && !CV->containsConstantExpression())
867+
return true;
868+
869+
if (CV->getType()->isVectorTy()) {
870+
if (auto *Splat = CV->getSplatValue(/*AllowPoison=*/true)) {
871+
if (!isa<ConstantExpr>(Splat) &&
872+
!Splat->containsConstantExpression()) {
873+
return true;
874+
}
875+
}
876+
}
877+
}
878+
return false;
879+
}
880+
};
881+
882+
struct match_immconstant_ty : immconstant_ty {
883+
template <typename ITy> bool match(ITy *V) { return isImmConstant(V); }
884+
};
885+
861886
/// Match an arbitrary immediate Constant and ignore it.
862-
inline match_combine_and<class_match<Constant>,
863-
match_unless<constantexpr_match>>
864-
m_ImmConstant() {
865-
return m_CombineAnd(m_Constant(), m_Unless(m_ConstantExpr()));
866-
}
887+
inline match_immconstant_ty m_ImmConstant() { return match_immconstant_ty(); }
888+
889+
struct bind_immconstant_ty : immconstant_ty {
890+
Constant *&VR;
891+
892+
bind_immconstant_ty(Constant *&V) : VR(V) {}
893+
894+
template <typename ITy> bool match(ITy *V) {
895+
if (isImmConstant(V)) {
896+
VR = cast<Constant>(V);
897+
return true;
898+
}
899+
return false;
900+
}
901+
};
867902

868903
/// Match an immediate Constant, capturing the value if we match.
869-
inline match_combine_and<bind_ty<Constant>,
870-
match_unless<constantexpr_match>>
871-
m_ImmConstant(Constant *&C) {
872-
return m_CombineAnd(m_Constant(C), m_Unless(m_ConstantExpr()));
904+
inline bind_immconstant_ty m_ImmConstant(Constant *&C) {
905+
return bind_immconstant_ty(C);
873906
}
874907

875908
/// Match a specified Value*.

llvm/test/Transforms/InstCombine/select.ll

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3519,8 +3519,7 @@ define <vscale x 2 x i32> @scalable_sign_bits(<vscale x 2 x i8> %x) {
35193519

35203520
define <vscale x 2 x i1> @scalable_non_zero(<vscale x 2 x i32> %x) {
35213521
; CHECK-LABEL: @scalable_non_zero(
3522-
; CHECK-NEXT: [[A:%.*]] = or <vscale x 2 x i32> [[X:%.*]], splat (i32 1)
3523-
; CHECK-NEXT: [[CMP:%.*]] = icmp ult <vscale x 2 x i32> [[A]], splat (i32 57)
3522+
; CHECK-NEXT: [[CMP:%.*]] = icmp ult <vscale x 2 x i32> [[X:%.*]], splat (i32 56)
35243523
; CHECK-NEXT: ret <vscale x 2 x i1> [[CMP]]
35253524
;
35263525
%a = or <vscale x 2 x i32> %x, splat (i32 1)

llvm/test/Transforms/InstCombine/shl-bo.ll

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -656,3 +656,14 @@ define <16 x i8> @test_FoldShiftByConstant_CreateAnd(<16 x i8> %in0) {
656656
%vshl_n = shl <16 x i8> %tmp, <i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5, i8 5>
657657
ret <16 x i8> %vshl_n
658658
}
659+
660+
define <vscale x 1 x i8> @test_FoldShiftByConstant_CreateAnd_scalable(<vscale x 1 x i8> %x) {
661+
; CHECK-LABEL: @test_FoldShiftByConstant_CreateAnd_scalable(
662+
; CHECK-NEXT: [[TMP1:%.*]] = shl <vscale x 1 x i8> [[X:%.*]], splat (i8 2)
663+
; CHECK-NEXT: [[TMP2:%.*]] = and <vscale x 1 x i8> [[TMP1]], splat (i8 8)
664+
; CHECK-NEXT: ret <vscale x 1 x i8> [[TMP2]]
665+
;
666+
%1 = and <vscale x 1 x i8> %x, splat (i8 2)
667+
%2 = shl <vscale x 1 x i8> %1, splat (i8 2)
668+
ret <vscale x 1 x i8> %2
669+
}

llvm/test/Transforms/InstCombine/shl-twice-constant.ll

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,14 @@ define i64 @testfunc() {
1414
%shl2 = shl i64 %shl1, ptrtoint (ptr @c to i64)
1515
ret i64 %shl2
1616
}
17+
18+
define <vscale x 1 x i64> @scalable() {
19+
; CHECK-LABEL: @scalable(
20+
; CHECK-NEXT: [[SHL1:%.*]] = shl nuw <vscale x 1 x i64> splat (i64 1), shufflevector (<vscale x 1 x i64> insertelement (<vscale x 1 x i64> poison, i64 ptrtoint (ptr @c2 to i64), i64 0), <vscale x 1 x i64> poison, <vscale x 1 x i32> zeroinitializer)
21+
; CHECK-NEXT: [[SHL2:%.*]] = shl <vscale x 1 x i64> [[SHL1]], shufflevector (<vscale x 1 x i64> insertelement (<vscale x 1 x i64> poison, i64 ptrtoint (ptr @c to i64), i64 0), <vscale x 1 x i64> poison, <vscale x 1 x i32> zeroinitializer)
22+
; CHECK-NEXT: ret <vscale x 1 x i64> [[SHL2]]
23+
;
24+
%shl1 = shl <vscale x 1 x i64> splat (i64 1), splat (i64 ptrtoint (ptr @c2 to i64))
25+
%shl2 = shl <vscale x 1 x i64> %shl1, splat (i64 ptrtoint (ptr @c to i64))
26+
ret <vscale x 1 x i64> %shl2
27+
}

llvm/test/Transforms/InstCombine/sub.ll

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -857,11 +857,9 @@ define <2 x i16> @test44vecminval(<2 x i16> %x) {
857857
ret <2 x i16> %sub
858858
}
859859

860-
; FIXME: This isn't combined to xor as above because the pattern in visitSub
861-
; uses m_ImmConstant which matches Constant but (explicitly) not ConstantExpr.
862860
define <vscale x 2 x i16> @test44scalablevecminval(<vscale x 2 x i16> %x) {
863861
; CHECK-LABEL: @test44scalablevecminval(
864-
; CHECK-NEXT: [[SUB:%.*]] = add <vscale x 2 x i16> [[X:%.*]], splat (i16 -32768)
862+
; CHECK-NEXT: [[SUB:%.*]] = xor <vscale x 2 x i16> [[X:%.*]], splat (i16 -32768)
865863
; CHECK-NEXT: ret <vscale x 2 x i16> [[SUB]]
866864
;
867865
%sub = sub nsw <vscale x 2 x i16> %x, splat (i16 -32768)

llvm/test/Transforms/InstSimplify/vec-icmp-of-cast.ll

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,3 +174,12 @@ define <2 x i1> @icmp_slt_sext_is_true_false(<2 x i8> %x) {
174174
%cmp = icmp slt <2 x i32> %xext, <i32 257, i32 -450>
175175
ret <2 x i1> %cmp
176176
}
177+
178+
define <vscale x 4 x i1> @icmp_ult_sext_scalable_splat_is_true(<vscale x 4 x i8> %x) {
179+
; CHECK-LABEL: @icmp_ult_sext_scalable_splat_is_true(
180+
; CHECK-NEXT: ret <vscale x 4 x i1> splat (i1 true)
181+
;
182+
%s = sext <vscale x 4 x i8> %x to <vscale x 4 x i64>
183+
%cmp = icmp slt <vscale x 4 x i64> %s, splat (i64 257)
184+
ret <vscale x 4 x i1> %cmp
185+
}

0 commit comments

Comments
 (0)