diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/include/llvm/IR/PatternMatch.h | 16 | ||||
| -rw-r--r-- | llvm/test/Transforms/InstSimplify/AndOrXor.ll | 8 |
2 files changed, 18 insertions, 6 deletions
diff --git a/llvm/include/llvm/IR/PatternMatch.h b/llvm/include/llvm/IR/PatternMatch.h index 6b2b22e82b9..072c6c5ece8 100644 --- a/llvm/include/llvm/IR/PatternMatch.h +++ b/llvm/include/llvm/IR/PatternMatch.h @@ -886,17 +886,21 @@ template <typename LHS_t> struct not_match { template <typename OpTy> bool match(OpTy *V) { if (auto *O = dyn_cast<Operator>(V)) - if (O->getOpcode() == Instruction::Xor) - return matchIfNot(O->getOperand(0), O->getOperand(1)); + if (O->getOpcode() == Instruction::Xor) { + if (isAllOnes(O->getOperand(1))) + return L.match(O->getOperand(0)); + if (isAllOnes(O->getOperand(0))) + return L.match(O->getOperand(1)); + } return false; } private: - bool matchIfNot(Value *LHS, Value *RHS) { - return (isa<ConstantInt>(RHS) || isa<ConstantDataVector>(RHS) || + bool isAllOnes(Value *V) { + return (isa<ConstantInt>(V) || isa<ConstantDataVector>(V) || // FIXME: Remove CV. - isa<ConstantVector>(RHS)) && - cast<Constant>(RHS)->isAllOnesValue() && L.match(LHS); + isa<ConstantVector>(V)) && + cast<Constant>(V)->isAllOnesValue(); } }; diff --git a/llvm/test/Transforms/InstSimplify/AndOrXor.ll b/llvm/test/Transforms/InstSimplify/AndOrXor.ll index 2d7eeae0fd0..a027c7e1828 100644 --- a/llvm/test/Transforms/InstSimplify/AndOrXor.ll +++ b/llvm/test/Transforms/InstSimplify/AndOrXor.ll @@ -865,3 +865,11 @@ define <2 x i8> @shl_undersized_mask_splat(<2 x i8> %x) { ret <2 x i8> %mask } +define i32 @reversed_not(i32 %a) { +; CHECK-LABEL: @reversed_not( +; CHECK-NEXT: ret i32 -1 +; + %nega = xor i32 -1, %a + %or = or i32 %a, %nega + ret i32 %or +} |

