[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