Skip to content

Commit df9e5ae

Browse files
lukel97dtcxzyw
andauthored
[InstCombine] Match scalable splats in m_ImmConstant (llvm#132522)
llvm#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 llvm#132245, and saw that the resulting vector and scalar forms were different. --------- Co-authored-by: Yingwei Zheng <[email protected]>
1 parent 564e04b commit df9e5ae

File tree

5 files changed

+66
-14
lines changed

5 files changed

+66
-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)

0 commit comments

Comments
 (0)