diff --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h index b3eeb1d7ba88a..2d27c19e1b85e 100644 --- a/llvm/include/llvm/IR/PatternMatch.h +++ b/llvm/include/llvm/IR/PatternMatch.h @@ -858,18 +858,51 @@ inline bind_ty 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 static bool isImmConstant(ITy *V) { + if (auto *CV = dyn_cast(V)) { + if (!isa(CV) && !CV->containsConstantExpression()) + return true; + + if (CV->getType()->isVectorTy()) { + if (auto *Splat = CV->getSplatValue(/*AllowPoison=*/true)) { + if (!isa(Splat) && + !Splat->containsConstantExpression()) { + return true; + } + } + } + } + return false; + } +}; + +struct match_immconstant_ty : immconstant_ty { + template bool match(ITy *V) { return isImmConstant(V); } +}; + /// Match an arbitrary immediate Constant and ignore it. -inline match_combine_and, - match_unless> -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 bool match(ITy *V) { + if (isImmConstant(V)) { + VR = cast(V); + return true; + } + return false; + } +}; /// Match an immediate Constant, capturing the value if we match. -inline match_combine_and, - match_unless> -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*. diff --git a/llvm/test/Transforms/InstCombine/select.ll b/llvm/test/Transforms/InstCombine/select.ll index 2078b795817f8..3d81b72dd232e 100644 --- a/llvm/test/Transforms/InstCombine/select.ll +++ b/llvm/test/Transforms/InstCombine/select.ll @@ -3519,8 +3519,7 @@ define @scalable_sign_bits( %x) { define @scalable_non_zero( %x) { ; CHECK-LABEL: @scalable_non_zero( -; CHECK-NEXT: [[A:%.*]] = or [[X:%.*]], splat (i32 1) -; CHECK-NEXT: [[CMP:%.*]] = icmp ult [[A]], splat (i32 57) +; CHECK-NEXT: [[CMP:%.*]] = icmp ult [[X:%.*]], splat (i32 56) ; CHECK-NEXT: ret [[CMP]] ; %a = or %x, splat (i32 1) diff --git a/llvm/test/Transforms/InstCombine/shl-bo.ll b/llvm/test/Transforms/InstCombine/shl-bo.ll index c32ac2eacb25a..5ee8716d5d119 100644 --- a/llvm/test/Transforms/InstCombine/shl-bo.ll +++ b/llvm/test/Transforms/InstCombine/shl-bo.ll @@ -656,3 +656,14 @@ define <16 x i8> @test_FoldShiftByConstant_CreateAnd(<16 x i8> %in0) { %vshl_n = shl <16 x i8> %tmp, ret <16 x i8> %vshl_n } + +define @test_FoldShiftByConstant_CreateAnd_scalable( %x) { +; CHECK-LABEL: @test_FoldShiftByConstant_CreateAnd_scalable( +; CHECK-NEXT: [[TMP1:%.*]] = shl [[X:%.*]], splat (i8 2) +; CHECK-NEXT: [[TMP2:%.*]] = and [[TMP1]], splat (i8 8) +; CHECK-NEXT: ret [[TMP2]] +; + %1 = and %x, splat (i8 2) + %2 = shl %1, splat (i8 2) + ret %2 +} diff --git a/llvm/test/Transforms/InstCombine/shl-twice-constant.ll b/llvm/test/Transforms/InstCombine/shl-twice-constant.ll index bbdd7fa3d1c40..151db29fe3e5f 100644 --- a/llvm/test/Transforms/InstCombine/shl-twice-constant.ll +++ b/llvm/test/Transforms/InstCombine/shl-twice-constant.ll @@ -14,3 +14,14 @@ define i64 @testfunc() { %shl2 = shl i64 %shl1, ptrtoint (ptr @c to i64) ret i64 %shl2 } + +define @scalable() { +; CHECK-LABEL: @scalable( +; CHECK-NEXT: [[SHL1:%.*]] = shl nuw splat (i64 1), shufflevector ( insertelement ( poison, i64 ptrtoint (ptr @c2 to i64), i64 0), poison, zeroinitializer) +; CHECK-NEXT: [[SHL2:%.*]] = shl [[SHL1]], shufflevector ( insertelement ( poison, i64 ptrtoint (ptr @c to i64), i64 0), poison, zeroinitializer) +; CHECK-NEXT: ret [[SHL2]] +; + %shl1 = shl splat (i64 1), splat (i64 ptrtoint (ptr @c2 to i64)) + %shl2 = shl %shl1, splat (i64 ptrtoint (ptr @c to i64)) + ret %shl2 +} diff --git a/llvm/test/Transforms/InstCombine/sub.ll b/llvm/test/Transforms/InstCombine/sub.ll index e89419d1f3838..81ecd8506514e 100644 --- a/llvm/test/Transforms/InstCombine/sub.ll +++ b/llvm/test/Transforms/InstCombine/sub.ll @@ -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 @test44scalablevecminval( %x) { ; CHECK-LABEL: @test44scalablevecminval( -; CHECK-NEXT: [[SUB:%.*]] = add [[X:%.*]], splat (i16 -32768) +; CHECK-NEXT: [[SUB:%.*]] = xor [[X:%.*]], splat (i16 -32768) ; CHECK-NEXT: ret [[SUB]] ; %sub = sub nsw %x, splat (i16 -32768)