Skip to content

Reapply "[InstCombine] Match scalable splats in m_ImmConstant (#132522)" #134262

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 42 additions & 9 deletions llvm/include/llvm/IR/PatternMatch.h
Original file line number Diff line number Diff line change
Expand Up @@ -858,18 +858,51 @@ inline bind_ty<const BasicBlock> m_BasicBlock(const BasicBlock *&V) {
return V;
}

// TODO: Remove once UseConstant{Int,FP}ForScalableSplat is enabled by default,
// and use m_Unless(m_ConstantExpr).
struct immconstant_ty {
template <typename ITy> static bool isImmConstant(ITy *V) {
if (auto *CV = dyn_cast<Constant>(V)) {
if (!isa<ConstantExpr>(CV) && !CV->containsConstantExpression())
return true;

if (CV->getType()->isVectorTy()) {
if (auto *Splat = CV->getSplatValue(/*AllowPoison=*/true)) {
if (!isa<ConstantExpr>(Splat) &&
!Splat->containsConstantExpression()) {
return true;
}
}
}
}
return false;
}
};

struct match_immconstant_ty : immconstant_ty {
template <typename ITy> bool match(ITy *V) { return isImmConstant(V); }
};

/// Match an arbitrary immediate Constant and ignore it.
inline match_combine_and<class_match<Constant>,
match_unless<constantexpr_match>>
m_ImmConstant() {
return m_CombineAnd(m_Constant(), m_Unless(m_ConstantExpr()));
}
inline match_immconstant_ty m_ImmConstant() { return match_immconstant_ty(); }

struct bind_immconstant_ty : immconstant_ty {
Constant *&VR;

bind_immconstant_ty(Constant *&V) : VR(V) {}

template <typename ITy> bool match(ITy *V) {
if (isImmConstant(V)) {
VR = cast<Constant>(V);
return true;
}
return false;
}
};

/// Match an immediate Constant, capturing the value if we match.
inline match_combine_and<bind_ty<Constant>,
match_unless<constantexpr_match>>
m_ImmConstant(Constant *&C) {
return m_CombineAnd(m_Constant(C), m_Unless(m_ConstantExpr()));
inline bind_immconstant_ty m_ImmConstant(Constant *&C) {
return bind_immconstant_ty(C);
}

/// Match a specified Value*.
Expand Down
3 changes: 1 addition & 2 deletions llvm/test/Transforms/InstCombine/select.ll
Original file line number Diff line number Diff line change
Expand Up @@ -3519,8 +3519,7 @@ define <vscale x 2 x i32> @scalable_sign_bits(<vscale x 2 x i8> %x) {

define <vscale x 2 x i1> @scalable_non_zero(<vscale x 2 x i32> %x) {
; CHECK-LABEL: @scalable_non_zero(
; CHECK-NEXT: [[A:%.*]] = or <vscale x 2 x i32> [[X:%.*]], splat (i32 1)
; CHECK-NEXT: [[CMP:%.*]] = icmp ult <vscale x 2 x i32> [[A]], splat (i32 57)
; CHECK-NEXT: [[CMP:%.*]] = icmp ult <vscale x 2 x i32> [[X:%.*]], splat (i32 56)
; CHECK-NEXT: ret <vscale x 2 x i1> [[CMP]]
;
%a = or <vscale x 2 x i32> %x, splat (i32 1)
Expand Down
11 changes: 11 additions & 0 deletions llvm/test/Transforms/InstCombine/shl-bo.ll
Original file line number Diff line number Diff line change
Expand Up @@ -656,3 +656,14 @@ define <16 x i8> @test_FoldShiftByConstant_CreateAnd(<16 x i8> %in0) {
%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>
ret <16 x i8> %vshl_n
}

define <vscale x 1 x i8> @test_FoldShiftByConstant_CreateAnd_scalable(<vscale x 1 x i8> %x) {
; CHECK-LABEL: @test_FoldShiftByConstant_CreateAnd_scalable(
; CHECK-NEXT: [[TMP1:%.*]] = shl <vscale x 1 x i8> [[X:%.*]], splat (i8 2)
; CHECK-NEXT: [[TMP2:%.*]] = and <vscale x 1 x i8> [[TMP1]], splat (i8 8)
; CHECK-NEXT: ret <vscale x 1 x i8> [[TMP2]]
;
%1 = and <vscale x 1 x i8> %x, splat (i8 2)
%2 = shl <vscale x 1 x i8> %1, splat (i8 2)
ret <vscale x 1 x i8> %2
}
11 changes: 11 additions & 0 deletions llvm/test/Transforms/InstCombine/shl-twice-constant.ll
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,14 @@ define i64 @testfunc() {
%shl2 = shl i64 %shl1, ptrtoint (ptr @c to i64)
ret i64 %shl2
}

define <vscale x 1 x i64> @scalable() {
; CHECK-LABEL: @scalable(
; 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)
; 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)
; CHECK-NEXT: ret <vscale x 1 x i64> [[SHL2]]
;
%shl1 = shl <vscale x 1 x i64> splat (i64 1), splat (i64 ptrtoint (ptr @c2 to i64))
%shl2 = shl <vscale x 1 x i64> %shl1, splat (i64 ptrtoint (ptr @c to i64))
ret <vscale x 1 x i64> %shl2
}
4 changes: 1 addition & 3 deletions llvm/test/Transforms/InstCombine/sub.ll
Original file line number Diff line number Diff line change
Expand Up @@ -857,11 +857,9 @@ define <2 x i16> @test44vecminval(<2 x i16> %x) {
ret <2 x i16> %sub
}

; FIXME: This isn't combined to xor as above because the pattern in visitSub
; uses m_ImmConstant which matches Constant but (explicitly) not ConstantExpr.
define <vscale x 2 x i16> @test44scalablevecminval(<vscale x 2 x i16> %x) {
; CHECK-LABEL: @test44scalablevecminval(
; CHECK-NEXT: [[SUB:%.*]] = add <vscale x 2 x i16> [[X:%.*]], splat (i16 -32768)
; CHECK-NEXT: [[SUB:%.*]] = xor <vscale x 2 x i16> [[X:%.*]], splat (i16 -32768)
; CHECK-NEXT: ret <vscale x 2 x i16> [[SUB]]
;
%sub = sub nsw <vscale x 2 x i16> %x, splat (i16 -32768)
Expand Down
9 changes: 9 additions & 0 deletions llvm/test/Transforms/InstSimplify/vec-icmp-of-cast.ll
Original file line number Diff line number Diff line change
Expand Up @@ -174,3 +174,12 @@ define <2 x i1> @icmp_slt_sext_is_true_false(<2 x i8> %x) {
%cmp = icmp slt <2 x i32> %xext, <i32 257, i32 -450>
ret <2 x i1> %cmp
}

define <vscale x 4 x i1> @icmp_ult_sext_scalable_splat_is_true(<vscale x 4 x i8> %x) {
; CHECK-LABEL: @icmp_ult_sext_scalable_splat_is_true(
; CHECK-NEXT: ret <vscale x 4 x i1> splat (i1 true)
;
%s = sext <vscale x 4 x i8> %x to <vscale x 4 x i64>
%cmp = icmp slt <vscale x 4 x i64> %s, splat (i64 257)
ret <vscale x 4 x i1> %cmp
}