[PATCH] D42818: [InstCombine][ValueTracking] Match non-uniform constant power-of-two vectors
Simon Pilgrim via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Thu Feb 1 14:25:26 PST 2018
RKSimon created this revision.
RKSimon added reviewers: efriedma, spatel, n.bozhenov, craig.topper.
Generalize existing constant matching to work with non-uniform constant vectors as well.
Repository:
rL LLVM
https://reviews.llvm.org/D42818
Files:
include/llvm/IR/PatternMatch.h
lib/Analysis/ValueTracking.cpp
test/Transforms/InstCombine/vector-urem.ll
Index: test/Transforms/InstCombine/vector-urem.ll
===================================================================
--- test/Transforms/InstCombine/vector-urem.ll
+++ test/Transforms/InstCombine/vector-urem.ll
@@ -3,16 +3,16 @@
define <4 x i32> @test_v4i32_splatconst_pow2(<4 x i32> %a0) {
; CHECK-LABEL: @test_v4i32_splatconst_pow2(
-; CHECK-NEXT: [[TMP1:%.*]] = and <4 x i32> %a0, <i32 1, i32 1, i32 1, i32 1>
+; CHECK-NEXT: [[TMP1:%.*]] = and <4 x i32> [[A0:%.*]], <i32 1, i32 1, i32 1, i32 1>
; CHECK-NEXT: ret <4 x i32> [[TMP1]]
;
%1 = urem <4 x i32> %a0, <i32 2, i32 2, i32 2, i32 2>
ret <4 x i32> %1
}
define <4 x i32> @test_v4i32_const_pow2(<4 x i32> %a0) {
; CHECK-LABEL: @test_v4i32_const_pow2(
-; CHECK-NEXT: [[TMP1:%.*]] = urem <4 x i32> %a0, <i32 1, i32 2, i32 4, i32 8>
+; CHECK-NEXT: [[TMP1:%.*]] = and <4 x i32> [[A0:%.*]], <i32 0, i32 1, i32 3, i32 7>
; CHECK-NEXT: ret <4 x i32> [[TMP1]]
;
%1 = urem <4 x i32> %a0, <i32 1, i32 2, i32 4, i32 8>
Index: lib/Analysis/ValueTracking.cpp
===================================================================
--- lib/Analysis/ValueTracking.cpp
+++ lib/Analysis/ValueTracking.cpp
@@ -1646,14 +1646,11 @@
const Query &Q) {
assert(Depth <= MaxDepth && "Limit Search Depth");
- if (const Constant *C = dyn_cast<Constant>(V)) {
- if (C->isNullValue())
- return OrZero;
-
- const APInt *ConstIntOrConstSplatInt;
- if (match(C, m_APInt(ConstIntOrConstSplatInt)))
- return ConstIntOrConstSplatInt->isPowerOf2();
- }
+ // Attempt to match against constants.
+ if (OrZero && match(V, m_Power2OrZero()))
+ return true;
+ if (match(V, m_Power2()))
+ return true;
// 1 << X is clearly a power of two if the one is not shifted off the end. If
// it is shifted off the end then the result is undefined.
Index: include/llvm/IR/PatternMatch.h
===================================================================
--- include/llvm/IR/PatternMatch.h
+++ include/llvm/IR/PatternMatch.h
@@ -289,10 +289,26 @@
template <typename ITy> bool match(ITy *V) {
if (const auto *CI = dyn_cast<ConstantInt>(V))
return this->isValue(CI->getValue());
- if (V->getType()->isVectorTy())
+ if (V->getType()->isVectorTy()) {
if (const auto *C = dyn_cast<Constant>(V))
if (const auto *CI = dyn_cast_or_null<ConstantInt>(C->getSplatValue()))
return this->isValue(CI->getValue());
+ if (const auto *CDV = dyn_cast<ConstantDataVector>(V)) {
+ unsigned E = CDV->getNumElements();
+ if (!E)
+ return false;
+ for (unsigned I = 0; I < E; ++I) {
+ if (const auto *CI =
+ dyn_cast_or_null<ConstantInt>(CDV->getElementAsConstant(I))) {
+ if (!this->isValue(CI->getValue()))
+ return false;
+ continue;
+ }
+ return false;
+ }
+ return true;
+ }
+ }
return false;
}
};
@@ -330,6 +346,14 @@
inline cst_pred_ty<is_power2> m_Power2() { return cst_pred_ty<is_power2>(); }
inline api_pred_ty<is_power2> m_Power2(const APInt *&V) { return V; }
+struct is_power2_or_zero {
+ bool isValue(const APInt &C) { return !C || C.isPowerOf2(); }
+};
+
+/// \brief Match an integer or vector of zero or power of 2 values.
+inline cst_pred_ty<is_power2_or_zero> m_Power2OrZero() { return cst_pred_ty<is_power2_or_zero>(); }
+inline api_pred_ty<is_power2_or_zero> m_Power2OrZero(const APInt *&V) { return V; }
+
struct is_maxsignedvalue {
bool isValue(const APInt &C) { return C.isMaxSignedValue(); }
};
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D42818.132474.patch
Type: text/x-patch
Size: 3694 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180201/701a6af1/attachment.bin>
More information about the llvm-commits
mailing list