[PATCH] D74228: [PatternMatch] Match XOR variant of unsigned-add overflow check.
Florian Hahn via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Feb 11 04:58:12 PST 2020
fhahn updated this revision to Diff 243816.
fhahn added a comment.
Document additional pattern match by UAddWithOverflow and add comment on why we match for AddInst explicitly in InstCombine.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D74228/new/
https://reviews.llvm.org/D74228
Files:
llvm/include/llvm/IR/PatternMatch.h
llvm/lib/CodeGen/CodeGenPrepare.cpp
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
llvm/test/Transforms/CodeGenPrepare/X86/overflow-intrinsics.ll
Index: llvm/test/Transforms/CodeGenPrepare/X86/overflow-intrinsics.ll
===================================================================
--- llvm/test/Transforms/CodeGenPrepare/X86/overflow-intrinsics.ll
+++ llvm/test/Transforms/CodeGenPrepare/X86/overflow-intrinsics.ll
@@ -101,6 +101,22 @@
ret i64 0
}
+; Instcombine folds (a + b <u a) to (a ^ -1 <u b). Make sure we match this
+; pattern as well.
+define i64 @uaddo6_xor(i64 %a, i64 %b) nounwind ssp {
+; CHECK-LABEL: @uaddo6_xor(
+; CHECK-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[A:%.*]], i64 [[B:%.*]])
+; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0
+; CHECK-NEXT: [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1
+; CHECK-NEXT: [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42
+; CHECK-NEXT: ret i64 [[Q]]
+;
+ %x = xor i64 %a, -1
+ %cmp = icmp ult i64 %x, %b
+ %Q = select i1 %cmp, i64 %b, i64 42
+ ret i64 %Q
+}
+
; When adding 1, the general pattern for add-overflow may be different due to icmp canonicalization.
; PR31754: https://bugs.llvm.org/show_bug.cgi?id=31754
Index: llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -5572,8 +5572,11 @@
isa<IntegerType>(A->getType())) {
Value *Result;
Constant *Overflow;
- if (OptimizeOverflowCheck(Instruction::Add, /*Signed*/false, A, B,
- *AddI, Result, Overflow)) {
+ // m_UAddWithOverflow can match patterns that do not include an explicit
+ // "add" instruction, so check the opcode of the matched op.
+ if (AddI->getOpcode() == Instruction::Add &&
+ OptimizeOverflowCheck(Instruction::Add, /*Signed*/ false, A, B, *AddI,
+ Result, Overflow)) {
replaceInstUsesWith(*AddI, Result);
return replaceInstUsesWith(I, Overflow);
}
Index: llvm/lib/CodeGen/CodeGenPrepare.cpp
===================================================================
--- llvm/lib/CodeGen/CodeGenPrepare.cpp
+++ llvm/lib/CodeGen/CodeGenPrepare.cpp
@@ -1201,13 +1201,16 @@
return false;
}
- // We allow matching the canonical IR (add X, C) back to (usubo X, -C).
Value *Arg0 = BO->getOperand(0);
Value *Arg1 = BO->getOperand(1);
+ // We allow matching the canonical IR (add X, C) back to (usubo X, -C).
if (BO->getOpcode() == Instruction::Add &&
IID == Intrinsic::usub_with_overflow) {
assert(isa<Constant>(Arg1) && "Unexpected input for usubo");
Arg1 = ConstantExpr::getNeg(cast<Constant>(Arg1));
+ } else if (BO->getOpcode() == Instruction::Xor) {
+ Arg0 = BO->getOperand(0);
+ Arg1 = Cmp->getOperand(1);
}
// Insert at the first instruction of the pair.
Index: llvm/include/llvm/IR/PatternMatch.h
===================================================================
--- llvm/include/llvm/IR/PatternMatch.h
+++ llvm/include/llvm/IR/PatternMatch.h
@@ -1674,7 +1674,8 @@
}
//===----------------------------------------------------------------------===//
-// Matchers for overflow check patterns: e.g. (a + b) u< a
+// Matchers for overflow check patterns: e.g. (a + b) u< a, (a ^ -1) <u b
+// Note that S might be matched to other instructions than AddInst.
//
template <typename LHS_t, typename RHS_t, typename Sum_t>
@@ -1705,6 +1706,13 @@
if (AddExpr.match(ICmpRHS) && (ICmpLHS == AddLHS || ICmpLHS == AddRHS))
return L.match(AddLHS) && R.match(AddRHS) && S.match(ICmpRHS);
+ // (a ^ -1) <u b
+ if (Pred == ICmpInst::ICMP_ULT) {
+ Value *Op1;
+ if (m_OneUse(m_Xor(m_Value(Op1), m_AllOnes())).match(ICmpLHS))
+ return L.match(Op1) && R.match(ICmpRHS) && S.match(ICmpLHS);
+ }
+
// Match special-case for increment-by-1.
if (Pred == ICmpInst::ICMP_EQ) {
// (a + 1) == 0
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D74228.243816.patch
Type: text/x-patch
Size: 3987 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200211/22c8044a/attachment.bin>
More information about the llvm-commits
mailing list