diff --git a/include/llvm/IR/PatternMatch.h b/include/llvm/IR/PatternMatch.h index 36b4a45ae22..2c579e4d628 100644 --- a/include/llvm/IR/PatternMatch.h +++ b/include/llvm/IR/PatternMatch.h @@ -182,17 +182,6 @@ struct match_nan { /// Match an arbitrary NaN constant. This includes quiet and signalling nans. inline match_nan m_NaN() { return match_nan(); } -struct match_all_ones { - template bool match(ITy *V) { - if (const auto *C = dyn_cast(V)) - return C->isAllOnesValue(); - return false; - } -}; - -/// Match an integer or vector with all bits set to true. -inline match_all_ones m_AllOnes() { return match_all_ones(); } - struct match_sign_mask { template bool match(ITy *V) { if (const auto *C = dyn_cast(V)) @@ -337,6 +326,14 @@ template struct api_pred_ty : public Predicate { // /////////////////////////////////////////////////////////////////////////////// +struct is_all_ones { + bool isValue(const APInt &C) { return C.isAllOnesValue(); } +}; +/// Match an integer or vector with all bits set. +inline cst_pred_ty m_AllOnes() { + return cst_pred_ty(); +} + struct is_maxsignedvalue { bool isValue(const APInt &C) { return C.isMaxSignedValue(); } }; diff --git a/lib/Analysis/InstructionSimplify.cpp b/lib/Analysis/InstructionSimplify.cpp index 34a10c5d5ea..a424e693842 100644 --- a/lib/Analysis/InstructionSimplify.cpp +++ b/lib/Analysis/InstructionSimplify.cpp @@ -1264,9 +1264,10 @@ static Value *SimplifyAShrInst(Value *Op0, Value *Op1, bool isExact, MaxRecurse)) return V; - // all ones >>a X -> all ones + // all ones >>a X -> -1 + // Do not return Op0 because it may contain undef elements if it's a vector. if (match(Op0, m_AllOnes())) - return Op0; + return Constant::getAllOnesValue(Op0->getType()); // (X << A) >> A -> X Value *X; @@ -1783,21 +1784,16 @@ static Value *SimplifyOrInst(Value *Op0, Value *Op1, const SimplifyQuery &Q, return C; // X | undef -> -1 - if (match(Op1, m_Undef())) + // X | -1 = -1 + // Do not return Op1 because it may contain undef elements if it's a vector. + if (match(Op1, m_Undef()) || match(Op1, m_AllOnes())) return Constant::getAllOnesValue(Op0->getType()); // X | X = X - if (Op0 == Op1) - return Op0; - // X | 0 = X - if (match(Op1, m_Zero())) + if (Op0 == Op1 || match(Op1, m_Zero())) return Op0; - // X | -1 = -1 - if (match(Op1, m_AllOnes())) - return Op1; - // A | ~A = ~A | A = -1 if (match(Op0, m_Not(m_Specific(Op1))) || match(Op1, m_Not(m_Specific(Op0)))) diff --git a/test/Transforms/InstSimplify/or.ll b/test/Transforms/InstSimplify/or.ll index e9b61b5ba98..20f67769eed 100644 --- a/test/Transforms/InstSimplify/or.ll +++ b/test/Transforms/InstSimplify/or.ll @@ -19,8 +19,7 @@ define i32 @all_ones(i32 %A) { define <3 x i8> @all_ones_vec_with_undef_elt(<3 x i8> %A) { ; CHECK-LABEL: @all_ones_vec_with_undef_elt( -; CHECK-NEXT: [[B:%.*]] = or <3 x i8> [[A:%.*]], -; CHECK-NEXT: ret <3 x i8> [[B]] +; CHECK-NEXT: ret <3 x i8> ; %B = or <3 x i8> %A, ret <3 x i8> %B diff --git a/test/Transforms/InstSimplify/shr-nop.ll b/test/Transforms/InstSimplify/shr-nop.ll index c0bdcaaede7..319d3196763 100644 --- a/test/Transforms/InstSimplify/shr-nop.ll +++ b/test/Transforms/InstSimplify/shr-nop.ll @@ -195,8 +195,7 @@ define i1 @ashr_ne_first_zero(i8 %a) { define <3 x i8> @ashr_all_ones_vec_with_undef_elts(<3 x i8> %x, <3 x i8> %y) { ; CHECK-LABEL: @ashr_all_ones_vec_with_undef_elts( -; CHECK-NEXT: [[SH:%.*]] = ashr <3 x i8> , [[Y:%.*]] -; CHECK-NEXT: ret <3 x i8> [[SH]] +; CHECK-NEXT: ret <3 x i8> ; %sh = ashr <3 x i8> , %y ret <3 x i8> %sh