1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-25 04:02:41 +01:00

Update m_Undef to match vectors/aggrs with undefs and poisons mixed

This fixes https://reviews.llvm.org/D93990#2666922
by teaching `m_Undef` to match vectors/aggrs with poison elements.

As suggested, fixes in InstCombine files to use the `m_Undef` matcher instead
of `isa<UndefValue>` will be followed.

Reviewed By: lebedev.ri

Differential Revision: https://reviews.llvm.org/D100122
This commit is contained in:
Juneyoung Lee 2021-04-18 10:57:04 +09:00
parent bd2bad88ac
commit e279a5783d
4 changed files with 82 additions and 5 deletions

View File

@ -37,6 +37,7 @@
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/PatternMatch.h"
namespace llvm {
@ -133,7 +134,9 @@ struct SimplifyQuery {
bool isUndefValue(Value *V) const {
if (!CanUseUndef)
return false;
return isa<UndefValue>(V);
using namespace PatternMatch;
return match(V, m_Undef());
}
};

View File

@ -88,8 +88,52 @@ inline class_match<BinaryOperator> m_BinOp() {
/// Matches any compare instruction and ignore it.
inline class_match<CmpInst> m_Cmp() { return class_match<CmpInst>(); }
/// Match an arbitrary undef constant.
inline class_match<UndefValue> m_Undef() { return class_match<UndefValue>(); }
struct undef_match {
static bool check(const Value *V) {
if (isa<UndefValue>(V))
return true;
const auto *CA = dyn_cast<ConstantAggregate>(V);
if (!CA)
return false;
SmallPtrSet<const ConstantAggregate *, 8> Seen;
SmallVector<const ConstantAggregate *, 8> Worklist;
// Either UndefValue, PoisonValue, or an aggregate that only contains
// these is accepted by matcher.
// CheckValue returns false if CA cannot satisfy this constraint.
auto CheckValue = [&](const ConstantAggregate *CA) {
for (const Value *Op : CA->operand_values()) {
if (isa<UndefValue>(Op))
continue;
const auto *CA = dyn_cast<ConstantAggregate>(Op);
if (!CA)
return false;
if (Seen.insert(CA).second)
Worklist.emplace_back(CA);
}
return true;
};
if (!CheckValue(CA))
return false;
while (!Worklist.empty()) {
if (!CheckValue(Worklist.pop_back_val()))
return false;
}
return true;
}
template <typename ITy> bool match(ITy *V) { return check(V); }
};
/// Match an arbitrary undef constant. This matches poison as well.
/// If this is an aggregate and contains a non-aggregate element that is
/// neither undef nor poison, the aggregate is not matched.
inline auto m_Undef() { return undef_match(); }
/// Match an arbitrary poison constant.
inline class_match<PoisonValue> m_Poison() { return class_match<PoisonValue>(); }

View File

@ -1069,8 +1069,7 @@ bb3:
define <2 x i1> @heterogeneous_constvector(<2 x i8> %x) {
; CHECK-LABEL: @heterogeneous_constvector(
; CHECK-NEXT: [[C:%.*]] = icmp ult <2 x i8> [[X:%.*]], <i8 undef, i8 poison>
; CHECK-NEXT: ret <2 x i1> [[C]]
; CHECK-NEXT: ret <2 x i1> zeroinitializer
;
%c = icmp ult <2 x i8> %x, <i8 undef, i8 poison>
ret <2 x i1> %c

View File

@ -1022,6 +1022,37 @@ TEST_F(PatternMatchTest, VectorOps) {
EXPECT_TRUE(A == Val);
}
TEST_F(PatternMatchTest, UndefPoisonMix) {
Type *ScalarTy = IRB.getInt8Ty();
ArrayType *ArrTy = ArrayType::get(ScalarTy, 2);
StructType *StTy = StructType::get(ScalarTy, ScalarTy);
StructType *StTy2 = StructType::get(ScalarTy, StTy);
StructType *StTy3 = StructType::get(StTy, ScalarTy);
Constant *Zero = ConstantInt::getNullValue(ScalarTy);
UndefValue *U = UndefValue::get(ScalarTy);
UndefValue *P = PoisonValue::get(ScalarTy);
EXPECT_TRUE(match(ConstantVector::get({U, P}), m_Undef()));
EXPECT_TRUE(match(ConstantVector::get({P, U}), m_Undef()));
EXPECT_TRUE(match(ConstantArray::get(ArrTy, {U, P}), m_Undef()));
EXPECT_TRUE(match(ConstantArray::get(ArrTy, {P, U}), m_Undef()));
auto *UP = ConstantStruct::get(StTy, {U, P});
EXPECT_TRUE(match(ConstantStruct::get(StTy2, {U, UP}), m_Undef()));
EXPECT_TRUE(match(ConstantStruct::get(StTy2, {P, UP}), m_Undef()));
EXPECT_TRUE(match(ConstantStruct::get(StTy3, {UP, U}), m_Undef()));
EXPECT_TRUE(match(ConstantStruct::get(StTy3, {UP, P}), m_Undef()));
EXPECT_FALSE(match(ConstantStruct::get(StTy, {U, Zero}), m_Undef()));
EXPECT_FALSE(match(ConstantStruct::get(StTy, {Zero, U}), m_Undef()));
EXPECT_FALSE(match(ConstantStruct::get(StTy, {P, Zero}), m_Undef()));
EXPECT_FALSE(match(ConstantStruct::get(StTy, {Zero, P}), m_Undef()));
EXPECT_FALSE(match(ConstantStruct::get(StTy2, {Zero, UP}), m_Undef()));
EXPECT_FALSE(match(ConstantStruct::get(StTy3, {UP, Zero}), m_Undef()));
}
TEST_F(PatternMatchTest, VectorUndefInt) {
Type *ScalarTy = IRB.getInt8Ty();
Type *VectorTy = FixedVectorType::get(ScalarTy, 4);