<div dir="ltr"><div>As I'm rummaging around here in CGP, I see another possibility:</div><div>We have a set of "RemovedInsts" populated by another transform that enables delayed deletion. I think we can have the overflow transforms use that. So we would RAUW, but not actually remove/delete the original cmp/add/sub when doing the overflow transforms. That would mean we don't need to mark the DT as modified in any way (we mark the DT as modified to prevent using a stale instruction iterator).</div><div><br></div><div>I'll post a draft of that change, so you can try that with your motivating tests.<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Apr 24, 2019 at 8:42 AM Sanjay Patel <<a href="mailto:spatel@rotateright.com">spatel@rotateright.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div>Hi Yevgeny,</div><div><br></div><div>I'm curious what size/mix of IR makes this a perf problem. That is, how many overflow intrinsics and how many instructions/blocks are in the problem function? If you can share an example file, that would be great.</div><div><br></div><div>You're correct that the CFG is not modified, so DomTreeUpdater might be a solution. But I had not seen DTU until just now, so if anyone with knowledge of that class has suggestions about how to use it here, I'd be grateful. :)<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Apr 23, 2019 at 9:42 PM Yevgeny Rouban <<a href="mailto:yevgeny.rouban@azul.com" target="_blank">yevgeny.rouban@azul.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">





<div lang="EN-US">
<div class="gmail-m_1938106320789593845gmail-m_-9122261492763692324WordSection1">
<p class="MsoNormal"><span style="color:rgb(31,73,125)">Hello Sanjay.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="color:rgb(31,73,125)"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="color:rgb(31,73,125)">We have all these changes integrated but still suffer from significant performance degradation.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="color:rgb(31,73,125)">I’d like to mention that the NFCI change
<a href="http://llvm.org/viewvc/llvm-project?view=revision&revision=354689" target="_blank">http://llvm.org/viewvc/llvm-project?view=revision&revision=354689</a> seems to introduce the complexity as it adds DomTree building not only to combineToUSubWithOverflow but also to
 combineToUAddWithOverflow().<u></u><u></u></span></p>
<p class="MsoNormal"><span style="color:rgb(31,73,125)"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="color:rgb(31,73,125)">The methods combineToUSubWithOverflow() and combineToUAddWithOverflow() seem to be keeping CFG intact. So I believe they should not trigger DT rebuild. In other words, they use DT but do not change it.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="color:rgb(31,73,125)">If I’m not right and DT needs to be rebuilt is it possible to make use of DomTreeUpdater wich should save performance in these cases?
<u></u><u></u></span></p>
<p class="MsoNormal"><span style="color:rgb(31,73,125)"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="color:rgb(31,73,125)">Thanks.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="color:rgb(31,73,125)">-Yevgeny Rouban<u></u><u></u></span></p>
<p class="MsoNormal"><span style="color:rgb(31,73,125)"><u></u> <u></u></span></p>
<p class="MsoNormal"><b>From:</b> Sanjay Patel <<a href="mailto:spatel@rotateright.com" target="_blank">spatel@rotateright.com</a>> <br>
<b>Sent:</b> Wednesday, April 24, 2019 1:12 AM<br>
<b>To:</b> Philip Reames <<a href="mailto:listmail@philipreames.com" target="_blank">listmail@philipreames.com</a>><br>
<b>Cc:</b> Teresa Johnson <<a href="mailto:tejohnson@google.com" target="_blank">tejohnson@google.com</a>>; Guozhi Wei <<a href="mailto:carrot@google.com" target="_blank">carrot@google.com</a>>; llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>>; Yevgeny Rouban <<a href="mailto:yevgeny.rouban@azul.com" target="_blank">yevgeny.rouban@azul.com</a>><br>
<b>Subject:</b> Re: [llvm] r354298 - [CGP] form usub with overflow from sub+icmp<u></u><u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<p class="MsoNormal">Philip,<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">Thanks for letting me know. For reference, here are possibly relevant changes to CGP that came after this commit:<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><a href="https://reviews.llvm.org/D58995" target="_blank">https://reviews.llvm.org/D58995</a> (rL355512)<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><a href="https://reviews.llvm.org/D59139" target="_blank">https://reviews.llvm.org/D59139</a> (rL355751)<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><a href="https://reviews.llvm.org/D59696" target="_blank">https://reviews.llvm.org/D59696</a> (rL356937)<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><a href="https://reviews.llvm.org/D59889" target="_blank">https://reviews.llvm.org/D59889</a> (rL357111)<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<div>
<p class="MsoNormal">On Tue, Apr 23, 2019 at 11:13 AM Philip Reames <<a href="mailto:listmail@philipreames.com" target="_blank">listmail@philipreames.com</a>> wrote:<u></u><u></u></p>
</div>
<blockquote style="border-color:currentcolor currentcolor currentcolor rgb(204,204,204);border-style:none none none solid;border-width:medium medium medium 1pt;padding:0in 0in 0in 6pt;margin-left:4.8pt;margin-right:0in">
<div>
<p>Sanjay,<u></u><u></u></p>
<p>We are also seeing fall out from this change.  We have a relatively widely felt compile time regression which appears to be triggered by this change.  The operating theory I've heard is that the use of dom tree is forcing many more rebuilds of a previously
 invalidated tree.  Yevgeny (CCd) can provide more information; he's worked around the problem in our downstream tree and can share his analysis. 
<u></u><u></u></p>
<p>Philip<u></u><u></u></p>
<div>
<p class="MsoNormal">On 3/13/19 9:54 PM, Teresa Johnson via llvm-commits wrote:<u></u><u></u></p>
</div>
<blockquote style="margin-top:5pt;margin-bottom:5pt">
<div>
<div>
<p class="MsoNormal">Hi Sanjay, <u></u><u></u></p>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">Unfortunately we are having some additional problems with this patch. One is a compiler assertion (which goes away after r355823 although since that patch just added a heuristic guard on the transformation it is likely just hidden). I filed <a href="https://bugs.llvm.org/show_bug.cgi?id=41064" target="_blank">https://bugs.llvm.org/show_bug.cgi?id=41064</a>
 for that one.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">The other is a performance slowdown. Carrot who is copied here can send you more info about that.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">Thanks,<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">Teresa<u></u><u></u></p>
</div>
</div>
</div>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<div>
<p class="MsoNormal">On Mon, Feb 18, 2019 at 3:32 PM Sanjay Patel via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>> wrote:<u></u><u></u></p>
</div>
<blockquote style="border-color:currentcolor currentcolor currentcolor rgb(204,204,204);border-style:none none none solid;border-width:medium medium medium 1pt;padding:0in 0in 0in 6pt;margin-left:4.8pt;margin-right:0in">
<p class="MsoNormal">Author: spatel<br>
Date: Mon Feb 18 15:33:05 2019<br>
New Revision: 354298<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=354298&view=rev" target="_blank">
http://llvm.org/viewvc/llvm-project?rev=354298&view=rev</a><br>
Log:<br>
[CGP] form usub with overflow from sub+icmp<br>
<br>
The motivating x86 cases for forming the intrinsic are shown in PR31754 and PR40487:<br>
<a href="https://bugs.llvm.org/show_bug.cgi?id=31754" target="_blank">https://bugs.llvm.org/show_bug.cgi?id=31754</a><br>
<a href="https://bugs.llvm.org/show_bug.cgi?id=40487" target="_blank">https://bugs.llvm.org/show_bug.cgi?id=40487</a><br>
..and those are shown in the IR test file and x86 codegen file.<br>
<br>
Matching the usubo pattern is harder than uaddo because we have 2 independent values rather than a def-use.<br>
<br>
This adds a TLI hook that should preserve the existing behavior for uaddo formation, but disables usubo<br>
formation by default. Only x86 overrides that setting for now although other targets will likely benefit<br>
by forming usbuo too.<br>
<br>
Differential Revision: <a href="https://reviews.llvm.org/D57789" target="_blank">
https://reviews.llvm.org/D57789</a><br>
<br>
Modified:<br>
    llvm/trunk/include/llvm/CodeGen/TargetLowering.h<br>
    llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp<br>
    llvm/trunk/lib/Target/X86/X86ISelLowering.cpp<br>
    llvm/trunk/lib/Target/X86/X86ISelLowering.h<br>
    llvm/trunk/test/CodeGen/X86/cgp-usubo.ll<br>
    llvm/trunk/test/CodeGen/X86/lsr-loop-exit-cond.ll<br>
    llvm/trunk/test/Transforms/CodeGenPrepare/X86/overflow-intrinsics.ll<br>
<br>
Modified: llvm/trunk/include/llvm/CodeGen/TargetLowering.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/TargetLowering.h?rev=354298&r1=354297&r2=354298&view=diff" target="_blank">
http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/TargetLowering.h?rev=354298&r1=354297&r2=354298&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/CodeGen/TargetLowering.h (original)<br>
+++ llvm/trunk/include/llvm/CodeGen/TargetLowering.h Mon Feb 18 15:33:05 2019<br>
@@ -2439,6 +2439,23 @@ public:<br>
     return false;<br>
   }<br>
<br>
+  /// Try to convert math with an overflow comparison into the corresponding DAG<br>
+  /// node operation. Targets may want to override this independently of whether<br>
+  /// the operation is legal/custom for the given type because it may obscure<br>
+  /// matching of other patterns.<br>
+  virtual bool shouldFormOverflowOp(unsigned Opcode, EVT VT) const {<br>
+    // TODO: The default logic is inherited from code in CodeGenPrepare.<br>
+    // The opcode should not make a difference by default?<br>
+    if (Opcode != ISD::UADDO)<br>
+      return false;<br>
+<br>
+    // Allow the transform as long as we have an integer type that is not<br>
+    // obviously illegal and unsupported.<br>
+    if (VT.isVector())<br>
+      return false;<br>
+    return VT.isSimple() || !isOperationExpand(Opcode, VT);<br>
+  }<br>
+<br>
   // Return true if it is profitable to use a scalar input to a BUILD_VECTOR<br>
   // even if the vector itself has multiple uses.<br>
   virtual bool aggressivelyPreferBuildVectorSources(EVT VecVT) const {<br>
<br>
Modified: llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp?rev=354298&r1=354297&r2=354298&view=diff" target="_blank">
http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp?rev=354298&r1=354297&r2=354298&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp (original)<br>
+++ llvm/trunk/lib/CodeGen/CodeGenPrepare.cpp Mon Feb 18 15:33:05 2019<br>
@@ -1162,9 +1162,18 @@ static bool OptimizeNoopCopyExpression(C<br>
 static void replaceMathCmpWithIntrinsic(BinaryOperator *BO, CmpInst *Cmp,<br>
                                         Instruction *InsertPt,<br>
                                         Intrinsic::ID IID) {<br>
+  Value *Arg0 = BO->getOperand(0);<br>
+  Value *Arg1 = BO->getOperand(1);<br>
+<br>
+  // We allow matching the canonical IR (add X, C) back to (usubo X, -C).<br>
+  if (BO->getOpcode() == Instruction::Add &&<br>
+      IID == Intrinsic::usub_with_overflow) {<br>
+    assert(isa<Constant>(Arg1) && "Unexpected input for usubo");<br>
+    Arg1 = ConstantExpr::getNeg(cast<Constant>(Arg1));<br>
+  }<br>
+<br>
   IRBuilder<> Builder(InsertPt);<br>
-  Value *MathOV = Builder.CreateBinaryIntrinsic(IID, BO->getOperand(0),<br>
-                                                BO->getOperand(1));<br>
+  Value *MathOV = Builder.CreateBinaryIntrinsic(IID, Arg0, Arg1);<br>
   Value *Math = Builder.CreateExtractValue(MathOV, 0, "math");<br>
   Value *OV = Builder.CreateExtractValue(MathOV, 1, "ov");<br>
   BO->replaceAllUsesWith(Math);<br>
@@ -1182,13 +1191,8 @@ static bool combineToUAddWithOverflow(Cm<br>
   if (!match(Cmp, m_UAddWithOverflow(m_Value(A), m_Value(B), m_BinOp(Add))))<br>
     return false;<br>
<br>
-  // Allow the transform as long as we have an integer type that is not<br>
-  // obviously illegal and unsupported.<br>
-  Type *Ty = Add->getType();<br>
-  if (!isa<IntegerType>(Ty))<br>
-    return false;<br>
-  EVT CodegenVT = TLI.getValueType(DL, Ty);<br>
-  if (!CodegenVT.isSimple() && TLI.isOperationExpand(ISD::UADDO, CodegenVT))<br>
+  if (!TLI.shouldFormOverflowOp(ISD::UADDO,<br>
+                                TLI.getValueType(DL, Add->getType())))<br>
     return false;<br>
<br>
   // We don't want to move around uses of condition values this late, so we<br>
@@ -1210,6 +1214,64 @@ static bool combineToUAddWithOverflow(Cm<br>
   return true;<br>
 }<br>
<br>
+static bool combineToUSubWithOverflow(CmpInst *Cmp, const TargetLowering &TLI,<br>
+                                      const DataLayout &DL, bool &ModifiedDT) {<br>
+  // Convert (A u> B) to (A u< B) to simplify pattern matching.<br>
+  Value *A = Cmp->getOperand(0), *B = Cmp->getOperand(1);<br>
+  ICmpInst::Predicate Pred = Cmp->getPredicate();<br>
+  if (Pred == ICmpInst::ICMP_UGT) {<br>
+    std::swap(A, B);<br>
+    Pred = ICmpInst::ICMP_ULT;<br>
+  }<br>
+  // Convert special-case: (A == 0) is the same as (A u< 1).<br>
+  if (Pred == ICmpInst::ICMP_EQ && match(B, m_ZeroInt())) {<br>
+    B = ConstantInt::get(B->getType(), 1);<br>
+    Pred = ICmpInst::ICMP_ULT;<br>
+  }<br>
+  if (Pred != ICmpInst::ICMP_ULT)<br>
+    return false;<br>
+<br>
+  // Walk the users of a variable operand of a compare looking for a subtract or<br>
+  // add with that same operand. Also match the 2nd operand of the compare to<br>
+  // the add/sub, but that may be a negated constant operand of an add.<br>
+  Value *CmpVariableOperand = isa<Constant>(A) ? B : A;<br>
+  BinaryOperator *Sub = nullptr;<br>
+  for (User *U : CmpVariableOperand->users()) {<br>
+    // A - B, A u< B --> usubo(A, B)<br>
+    if (match(U, m_Sub(m_Specific(A), m_Specific(B)))) {<br>
+      Sub = cast<BinaryOperator>(U);<br>
+      break;<br>
+    }<br>
+<br>
+    // A + (-C), A u< C (canonicalized form of (sub A, C))<br>
+    const APInt *CmpC, *AddC;<br>
+    if (match(U, m_Add(m_Specific(A), m_APInt(AddC))) &&<br>
+        match(B, m_APInt(CmpC)) && *AddC == -(*CmpC)) {<br>
+      Sub = cast<BinaryOperator>(U);<br>
+      break;<br>
+    }<br>
+  }<br>
+  if (!Sub)<br>
+    return false;<br>
+<br>
+  if (!TLI.shouldFormOverflowOp(ISD::USUBO,<br>
+                                TLI.getValueType(DL, Sub->getType())))<br>
+    return false;<br>
+<br>
+  // Pattern matched and profitability checked. Check dominance to determine the<br>
+  // insertion point for an intrinsic that replaces the subtract and compare.<br>
+  DominatorTree DT(*Sub->getFunction());<br>
+  bool SubDominates = DT.dominates(Sub, Cmp);<br>
+  if (!SubDominates && !DT.dominates(Cmp, Sub))<br>
+    return false;<br>
+  Instruction *InPt = SubDominates ? cast<Instruction>(Sub)<br>
+                                   : cast<Instruction>(Cmp);<br>
+  replaceMathCmpWithIntrinsic(Sub, Cmp, InPt, Intrinsic::usub_with_overflow);<br>
+  // Reset callers - do not crash by iterating over a dead instruction.<br>
+  ModifiedDT = true;<br>
+  return true;<br>
+}<br>
+<br>
 /// Sink the given CmpInst into user blocks to reduce the number of virtual<br>
 /// registers that must be created and coalesced. This is a clear win except on<br>
 /// targets with multiple condition code registers (PowerPC), where it might<br>
@@ -1276,14 +1338,17 @@ static bool sinkCmpExpression(CmpInst *C<br>
   return MadeChange;<br>
 }<br>
<br>
-static bool optimizeCmpExpression(CmpInst *Cmp, const TargetLowering &TLI,<br>
-                                  const DataLayout &DL) {<br>
+static bool optimizeCmp(CmpInst *Cmp, const TargetLowering &TLI,<br>
+                        const DataLayout &DL, bool &ModifiedDT) {<br>
   if (sinkCmpExpression(Cmp, TLI))<br>
     return true;<br>
<br>
   if (combineToUAddWithOverflow(Cmp, TLI, DL))<br>
     return true;<br>
<br>
+  if (combineToUSubWithOverflow(Cmp, TLI, DL, ModifiedDT))<br>
+    return true;<br>
+<br>
   return false;<br>
 }<br>
<br>
@@ -6770,8 +6835,8 @@ bool CodeGenPrepare::optimizeInst(Instru<br>
     return false;<br>
   }<br>
<br>
-  if (CmpInst *CI = dyn_cast<CmpInst>(I))<br>
-    if (TLI && optimizeCmpExpression(CI, *TLI, *DL))<br>
+  if (auto *Cmp = dyn_cast<CmpInst>(I))<br>
+    if (TLI && optimizeCmp(Cmp, *TLI, *DL, ModifiedDT))<br>
       return true;<br>
<br>
   if (LoadInst *LI = dyn_cast<LoadInst>(I)) {<br>
<br>
Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=354298&r1=354297&r2=354298&view=diff" target="_blank">
http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=354298&r1=354297&r2=354298&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)<br>
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Mon Feb 18 15:33:05 2019<br>
@@ -4934,6 +4934,13 @@ bool X86TargetLowering::shouldScalarizeB<br>
   return isOperationLegalOrCustomOrPromote(VecOp.getOpcode(), ScalarVT);<br>
 }<br>
<br>
+bool X86TargetLowering::shouldFormOverflowOp(unsigned Opcode, EVT VT) const {<br>
+  // TODO: Allow vectors?<br>
+  if (VT.isVector())<br>
+    return false;<br>
+  return VT.isSimple() || !isOperationExpand(Opcode, VT);<br>
+}<br>
+<br>
 bool X86TargetLowering::isCheapToSpeculateCttz() const {<br>
   // Speculate cttz only if we can directly use TZCNT.<br>
   return Subtarget.hasBMI();<br>
<br>
Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=354298&r1=354297&r2=354298&view=diff" target="_blank">
http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=354298&r1=354297&r2=354298&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original)<br>
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Mon Feb 18 15:33:05 2019<br>
@@ -1071,6 +1071,11 @@ namespace llvm {<br>
     /// supported.<br>
     bool shouldScalarizeBinop(SDValue) const override;<br>
<br>
+    /// Overflow nodes should get combined/lowered to optimal instructions<br>
+    /// (they should allow eliminating explicit compares by getting flags from<br>
+    /// math ops).<br>
+    bool shouldFormOverflowOp(unsigned Opcode, EVT VT) const override;<br>
+<br>
     bool storeOfVectorConstantIsCheap(EVT MemVT, unsigned NumElem,<br>
                                       unsigned AddrSpace) const override {<br>
       // If we can replace more than 2 scalar stores, there will be a reduction<br>
<br>
Modified: llvm/trunk/test/CodeGen/X86/cgp-usubo.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/cgp-usubo.ll?rev=354298&r1=354297&r2=354298&view=diff" target="_blank">
http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/cgp-usubo.ll?rev=354298&r1=354297&r2=354298&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/X86/cgp-usubo.ll (original)<br>
+++ llvm/trunk/test/CodeGen/X86/cgp-usubo.ll Mon Feb 18 15:33:05 2019<br>
@@ -7,8 +7,8 @@ define i1 @usubo_ult_i64(i64 %x, i64 %y,<br>
 ; CHECK-LABEL: usubo_ult_i64:<br>
 ; CHECK:       # %bb.0:<br>
 ; CHECK-NEXT:    subq %rsi, %rdi<br>
-; CHECK-NEXT:    movq %rdi, (%rdx)<br>
 ; CHECK-NEXT:    setb %al<br>
+; CHECK-NEXT:    movq %rdi, (%rdx)<br>
 ; CHECK-NEXT:    retq<br>
   %s = sub i64 %x, %y<br>
   store i64 %s, i64* %p<br>
@@ -21,9 +21,8 @@ define i1 @usubo_ult_i64(i64 %x, i64 %y,<br>
 define i1 @usubo_ugt_i32(i32 %x, i32 %y, i32* %p) nounwind {<br>
 ; CHECK-LABEL: usubo_ugt_i32:<br>
 ; CHECK:       # %bb.0:<br>
-; CHECK-NEXT:    cmpl %edi, %esi<br>
-; CHECK-NEXT:    seta %al<br>
 ; CHECK-NEXT:    subl %esi, %edi<br>
+; CHECK-NEXT:    setb %al<br>
 ; CHECK-NEXT:    movl %edi, (%rdx)<br>
 ; CHECK-NEXT:    retq<br>
   %ov = icmp ugt i32 %y, %x<br>
@@ -39,8 +38,7 @@ define i1 @usubo_ugt_constant_op0_i8(i8<br>
 ; CHECK:       # %bb.0:<br>
 ; CHECK-NEXT:    movb $42, %cl<br>
 ; CHECK-NEXT:    subb %dil, %cl<br>
-; CHECK-NEXT:    cmpb $42, %dil<br>
-; CHECK-NEXT:    seta %al<br>
+; CHECK-NEXT:    setb %al<br>
 ; CHECK-NEXT:    movb %cl, (%rsi)<br>
 ; CHECK-NEXT:    retq<br>
   %s = sub i8 42, %x<br>
@@ -54,10 +52,9 @@ define i1 @usubo_ugt_constant_op0_i8(i8<br>
 define i1 @usubo_ult_constant_op0_i16(i16 %x, i16* %p) nounwind {<br>
 ; CHECK-LABEL: usubo_ult_constant_op0_i16:<br>
 ; CHECK:       # %bb.0:<br>
-; CHECK-NEXT:    movl $43, %ecx<br>
-; CHECK-NEXT:    subl %edi, %ecx<br>
-; CHECK-NEXT:    cmpw $43, %di<br>
-; CHECK-NEXT:    seta %al<br>
+; CHECK-NEXT:    movw $43, %cx<br>
+; CHECK-NEXT:    subw %di, %cx<br>
+; CHECK-NEXT:    setb %al<br>
 ; CHECK-NEXT:    movw %cx, (%rsi)<br>
 ; CHECK-NEXT:    retq<br>
   %s = sub i16 43, %x<br>
@@ -71,11 +68,9 @@ define i1 @usubo_ult_constant_op0_i16(i1<br>
 define i1 @usubo_ult_constant_op1_i16(i16 %x, i16* %p) nounwind {<br>
 ; CHECK-LABEL: usubo_ult_constant_op1_i16:<br>
 ; CHECK:       # %bb.0:<br>
-; CHECK-NEXT:    movl %edi, %ecx<br>
-; CHECK-NEXT:    addl $-44, %ecx<br>
-; CHECK-NEXT:    cmpw $44, %di<br>
+; CHECK-NEXT:    subw $44, %di<br>
 ; CHECK-NEXT:    setb %al<br>
-; CHECK-NEXT:    movw %cx, (%rsi)<br>
+; CHECK-NEXT:    movw %di, (%rsi)<br>
 ; CHECK-NEXT:    retq<br>
   %s = add i16 %x, -44<br>
   %ov = icmp ult i16 %x, 44<br>
@@ -86,9 +81,8 @@ define i1 @usubo_ult_constant_op1_i16(i1<br>
 define i1 @usubo_ugt_constant_op1_i8(i8 %x, i8* %p) nounwind {<br>
 ; CHECK-LABEL: usubo_ugt_constant_op1_i8:<br>
 ; CHECK:       # %bb.0:<br>
-; CHECK-NEXT:    cmpb $45, %dil<br>
+; CHECK-NEXT:    subb $45, %dil<br>
 ; CHECK-NEXT:    setb %al<br>
-; CHECK-NEXT:    addb $-45, %dil<br>
 ; CHECK-NEXT:    movb %dil, (%rsi)<br>
 ; CHECK-NEXT:    retq<br>
   %ov = icmp ugt i8 45, %x<br>
@@ -102,11 +96,9 @@ define i1 @usubo_ugt_constant_op1_i8(i8<br>
 define i1 @usubo_eq_constant1_op1_i32(i32 %x, i32* %p) nounwind {<br>
 ; CHECK-LABEL: usubo_eq_constant1_op1_i32:<br>
 ; CHECK:       # %bb.0:<br>
-; CHECK-NEXT:    # kill: def $edi killed $edi def $rdi<br>
-; CHECK-NEXT:    leal -1(%rdi), %ecx<br>
-; CHECK-NEXT:    testl %edi, %edi<br>
-; CHECK-NEXT:    sete %al<br>
-; CHECK-NEXT:    movl %ecx, (%rsi)<br>
+; CHECK-NEXT:    subl $1, %edi<br>
+; CHECK-NEXT:    setb %al<br>
+; CHECK-NEXT:    movl %edi, (%rsi)<br>
 ; CHECK-NEXT:    retq<br>
   %s = add i32 %x, -1<br>
   %ov = icmp eq i32 %x, 0<br>
@@ -124,17 +116,14 @@ define i1 @usubo_ult_sub_dominates_i64(i<br>
 ; CHECK-NEXT:    testb $1, %cl<br>
 ; CHECK-NEXT:    je .LBB7_2<br>
 ; CHECK-NEXT:  # %bb.1: # %t<br>
-; CHECK-NEXT:    movq %rdi, %rax<br>
-; CHECK-NEXT:    subq %rsi, %rax<br>
-; CHECK-NEXT:    movq %rax, (%rdx)<br>
-; CHECK-NEXT:    testb $1, %cl<br>
-; CHECK-NEXT:    je .LBB7_2<br>
-; CHECK-NEXT:  # %bb.3: # %end<br>
-; CHECK-NEXT:    cmpq %rsi, %rdi<br>
+; CHECK-NEXT:    subq %rsi, %rdi<br>
 ; CHECK-NEXT:    setb %al<br>
-; CHECK-NEXT:    retq<br>
+; CHECK-NEXT:    movq %rdi, (%rdx)<br>
+; CHECK-NEXT:    testb $1, %cl<br>
+; CHECK-NEXT:    jne .LBB7_3<br>
 ; CHECK-NEXT:  .LBB7_2: # %f<br>
 ; CHECK-NEXT:    movl %ecx, %eax<br>
+; CHECK-NEXT:  .LBB7_3: # %end<br>
 ; CHECK-NEXT:    retq<br>
 entry:<br>
   br i1 %cond, label %t, label %f<br>
<br>
Modified: llvm/trunk/test/CodeGen/X86/lsr-loop-exit-cond.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/lsr-loop-exit-cond.ll?rev=354298&r1=354297&r2=354298&view=diff" target="_blank">
http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/lsr-loop-exit-cond.ll?rev=354298&r1=354297&r2=354298&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/CodeGen/X86/lsr-loop-exit-cond.ll (original)<br>
+++ llvm/trunk/test/CodeGen/X86/lsr-loop-exit-cond.ll Mon Feb 18 15:33:05 2019<br>
@@ -16,11 +16,11 @@ define void @t(i8* nocapture %in, i8* no<br>
 ; GENERIC-NEXT:    movl (%rdx), %eax<br>
 ; GENERIC-NEXT:    movl 4(%rdx), %ebx<br>
 ; GENERIC-NEXT:    decl %ecx<br>
-; GENERIC-NEXT:    leaq 20(%rdx), %r14<br>
+; GENERIC-NEXT:    leaq 20(%rdx), %r11<br>
 ; GENERIC-NEXT:    movq <a href="mailto:_Te0@%7b%7b.*%7d%7d(%25rip)" target="_blank">_Te0@{{.*}}(%rip)</a>, %r9<br>
 ; GENERIC-NEXT:    movq <a href="mailto:_Te1@%7b%7b.*%7d%7d(%25rip)" target="_blank">_Te1@{{.*}}(%rip)</a>, %r8<br>
 ; GENERIC-NEXT:    movq <a href="mailto:_Te3@%7b%7b.*%7d%7d(%25rip)" target="_blank">_Te3@{{.*}}(%rip)</a>, %r10<br>
-; GENERIC-NEXT:    movq %rcx, %r11<br>
+; GENERIC-NEXT:    movq %rcx, %r14<br>
 ; GENERIC-NEXT:    jmp LBB0_1<br>
 ; GENERIC-NEXT:    .p2align 4, 0x90<br>
 ; GENERIC-NEXT:  LBB0_2: ## %bb1<br>
@@ -29,14 +29,13 @@ define void @t(i8* nocapture %in, i8* no<br>
 ; GENERIC-NEXT:    shrl $16, %ebx<br>
 ; GENERIC-NEXT:    movzbl %bl, %ebx<br>
 ; GENERIC-NEXT:    xorl (%r8,%rbx,4), %eax<br>
-; GENERIC-NEXT:    xorl -4(%r14), %eax<br>
+; GENERIC-NEXT:    xorl -4(%r11), %eax<br>
 ; GENERIC-NEXT:    shrl $24, %edi<br>
 ; GENERIC-NEXT:    movzbl %bpl, %ebx<br>
 ; GENERIC-NEXT:    movl (%r10,%rbx,4), %ebx<br>
 ; GENERIC-NEXT:    xorl (%r9,%rdi,4), %ebx<br>
-; GENERIC-NEXT:    xorl (%r14), %ebx<br>
-; GENERIC-NEXT:    decq %r11<br>
-; GENERIC-NEXT:    addq $16, %r14<br>
+; GENERIC-NEXT:    xorl (%r11), %ebx<br>
+; GENERIC-NEXT:    addq $16, %r11<br>
 ; GENERIC-NEXT:  LBB0_1: ## %bb<br>
 ; GENERIC-NEXT:    ## =>This Inner Loop Header: Depth=1<br>
 ; GENERIC-NEXT:    movzbl %al, %edi<br>
@@ -47,16 +46,16 @@ define void @t(i8* nocapture %in, i8* no<br>
 ; GENERIC-NEXT:    movzbl %bpl, %ebp<br>
 ; GENERIC-NEXT:    movl (%r8,%rbp,4), %ebp<br>
 ; GENERIC-NEXT:    xorl (%r9,%rax,4), %ebp<br>
-; GENERIC-NEXT:    xorl -12(%r14), %ebp<br>
+; GENERIC-NEXT:    xorl -12(%r11), %ebp<br>
 ; GENERIC-NEXT:    shrl $24, %ebx<br>
 ; GENERIC-NEXT:    movl (%r10,%rdi,4), %edi<br>
 ; GENERIC-NEXT:    xorl (%r9,%rbx,4), %edi<br>
-; GENERIC-NEXT:    xorl -8(%r14), %edi<br>
+; GENERIC-NEXT:    xorl -8(%r11), %edi<br>
 ; GENERIC-NEXT:    movl %ebp, %eax<br>
 ; GENERIC-NEXT:    shrl $24, %eax<br>
 ; GENERIC-NEXT:    movl (%r9,%rax,4), %eax<br>
-; GENERIC-NEXT:    testq %r11, %r11<br>
-; GENERIC-NEXT:    jne LBB0_2<br>
+; GENERIC-NEXT:    subq $1, %r14<br>
+; GENERIC-NEXT:    jae LBB0_2<br>
 ; GENERIC-NEXT:  ## %bb.3: ## %bb2<br>
 ; GENERIC-NEXT:    shlq $4, %rcx<br>
 ; GENERIC-NEXT:    andl $-16777216, %eax ## imm = 0xFF000000<br>
@@ -99,27 +98,26 @@ define void @t(i8* nocapture %in, i8* no<br>
 ; ATOM-NEXT:    ## kill: def $ecx killed $ecx def $rcx<br>
 ; ATOM-NEXT:    movl (%rdx), %r15d<br>
 ; ATOM-NEXT:    movl 4(%rdx), %eax<br>
-; ATOM-NEXT:    leaq 20(%rdx), %r14<br>
+; ATOM-NEXT:    leaq 20(%rdx), %r11<br>
 ; ATOM-NEXT:    movq <a href="mailto:_Te0@%7b%7b.*%7d%7d(%25rip)" target="_blank">_Te0@{{.*}}(%rip)</a>, %r9<br>
 ; ATOM-NEXT:    movq <a href="mailto:_Te1@%7b%7b.*%7d%7d(%25rip)" target="_blank">_Te1@{{.*}}(%rip)</a>, %r8<br>
 ; ATOM-NEXT:    movq <a href="mailto:_Te3@%7b%7b.*%7d%7d(%25rip)" target="_blank">_Te3@{{.*}}(%rip)</a>, %r10<br>
 ; ATOM-NEXT:    decl %ecx<br>
-; ATOM-NEXT:    movq %rcx, %r11<br>
+; ATOM-NEXT:    movq %rcx, %r14<br>
 ; ATOM-NEXT:    jmp LBB0_1<br>
 ; ATOM-NEXT:    .p2align 4, 0x90<br>
 ; ATOM-NEXT:  LBB0_2: ## %bb1<br>
 ; ATOM-NEXT:    ## in Loop: Header=BB0_1 Depth=1<br>
 ; ATOM-NEXT:    shrl $16, %eax<br>
 ; ATOM-NEXT:    shrl $24, %edi<br>
-; ATOM-NEXT:    decq %r11<br>
-; ATOM-NEXT:    movzbl %al, %ebp<br>
+; ATOM-NEXT:    movzbl %al, %eax<br>
+; ATOM-NEXT:    xorl (%r8,%rax,4), %r15d<br>
 ; ATOM-NEXT:    movzbl %bl, %eax<br>
 ; ATOM-NEXT:    movl (%r10,%rax,4), %eax<br>
-; ATOM-NEXT:    xorl (%r8,%rbp,4), %r15d<br>
+; ATOM-NEXT:    xorl -4(%r11), %r15d<br>
 ; ATOM-NEXT:    xorl (%r9,%rdi,4), %eax<br>
-; ATOM-NEXT:    xorl -4(%r14), %r15d<br>
-; ATOM-NEXT:    xorl (%r14), %eax<br>
-; ATOM-NEXT:    addq $16, %r14<br>
+; ATOM-NEXT:    xorl (%r11), %eax<br>
+; ATOM-NEXT:    addq $16, %r11<br>
 ; ATOM-NEXT:  LBB0_1: ## %bb<br>
 ; ATOM-NEXT:    ## =>This Inner Loop Header: Depth=1<br>
 ; ATOM-NEXT:    movl %eax, %edi<br>
@@ -132,15 +130,15 @@ define void @t(i8* nocapture %in, i8* no<br>
 ; ATOM-NEXT:    movzbl %r15b, %edi<br>
 ; ATOM-NEXT:    xorl (%r9,%rbp,4), %ebx<br>
 ; ATOM-NEXT:    movl (%r10,%rdi,4), %edi<br>
-; ATOM-NEXT:    xorl -12(%r14), %ebx<br>
+; ATOM-NEXT:    xorl -12(%r11), %ebx<br>
 ; ATOM-NEXT:    xorl (%r9,%rax,4), %edi<br>
 ; ATOM-NEXT:    movl %ebx, %eax<br>
-; ATOM-NEXT:    xorl -8(%r14), %edi<br>
+; ATOM-NEXT:    xorl -8(%r11), %edi<br>
 ; ATOM-NEXT:    shrl $24, %eax<br>
 ; ATOM-NEXT:    movl (%r9,%rax,4), %r15d<br>
-; ATOM-NEXT:    testq %r11, %r11<br>
+; ATOM-NEXT:    subq $1, %r14<br>
 ; ATOM-NEXT:    movl %edi, %eax<br>
-; ATOM-NEXT:    jne LBB0_2<br>
+; ATOM-NEXT:    jae LBB0_2<br>
 ; ATOM-NEXT:  ## %bb.3: ## %bb2<br>
 ; ATOM-NEXT:    shrl $16, %eax<br>
 ; ATOM-NEXT:    shrl $8, %edi<br>
<br>
Modified: llvm/trunk/test/Transforms/CodeGenPrepare/X86/overflow-intrinsics.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/CodeGenPrepare/X86/overflow-intrinsics.ll?rev=354298&r1=354297&r2=354298&view=diff" target="_blank">
http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/CodeGenPrepare/X86/overflow-intrinsics.ll?rev=354298&r1=354297&r2=354298&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/Transforms/CodeGenPrepare/X86/overflow-intrinsics.ll (original)<br>
+++ llvm/trunk/test/Transforms/CodeGenPrepare/X86/overflow-intrinsics.ll Mon Feb 18 15:33:05 2019<br>
@@ -175,10 +175,11 @@ define i1 @uaddo_i42_increment_illegal_t<br>
<br>
 define i1 @usubo_ult_i64(i64 %x, i64 %y, i64* %p) {<br>
 ; CHECK-LABEL: @usubo_ult_i64(<br>
-; CHECK-NEXT:    [[S:%.*]] = sub i64 [[X:%.*]], [[Y:%.*]]<br>
-; CHECK-NEXT:    store i64 [[S]], i64* [[P:%.*]]<br>
-; CHECK-NEXT:    [[OV:%.*]] = icmp ult i64 [[X]], [[Y]]<br>
-; CHECK-NEXT:    ret i1 [[OV]]<br>
+; CHECK-NEXT:    [[TMP1:%.*]] = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 [[X:%.*]], i64 [[Y:%.*]])<br>
+; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0<br>
+; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1<br>
+; CHECK-NEXT:    store i64 [[MATH]], i64* [[P:%.*]]<br>
+; CHECK-NEXT:    ret i1 [[OV1]]<br>
 ;<br>
   %s = sub i64 %x, %y<br>
   store i64 %s, i64* %p<br>
@@ -190,10 +191,11 @@ define i1 @usubo_ult_i64(i64 %x, i64 %y,<br>
<br>
 define i1 @usubo_ugt_i32(i32 %x, i32 %y, i32* %p) {<br>
 ; CHECK-LABEL: @usubo_ugt_i32(<br>
-; CHECK-NEXT:    [[OV:%.*]] = icmp ugt i32 [[Y:%.*]], [[X:%.*]]<br>
-; CHECK-NEXT:    [[S:%.*]] = sub i32 [[X]], [[Y]]<br>
-; CHECK-NEXT:    store i32 [[S]], i32* [[P:%.*]]<br>
-; CHECK-NEXT:    ret i1 [[OV]]<br>
+; CHECK-NEXT:    [[TMP1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[X:%.*]], i32 [[Y:%.*]])<br>
+; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0<br>
+; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1<br>
+; CHECK-NEXT:    store i32 [[MATH]], i32* [[P:%.*]]<br>
+; CHECK-NEXT:    ret i1 [[OV1]]<br>
 ;<br>
   %ov = icmp ugt i32 %y, %x<br>
   %s = sub i32 %x, %y<br>
@@ -205,10 +207,11 @@ define i1 @usubo_ugt_i32(i32 %x, i32 %y,<br>
<br>
 define i1 @usubo_ugt_constant_op0_i8(i8 %x, i8* %p) {<br>
 ; CHECK-LABEL: @usubo_ugt_constant_op0_i8(<br>
-; CHECK-NEXT:    [[S:%.*]] = sub i8 42, [[X:%.*]]<br>
-; CHECK-NEXT:    [[OV:%.*]] = icmp ugt i8 [[X]], 42<br>
-; CHECK-NEXT:    store i8 [[S]], i8* [[P:%.*]]<br>
-; CHECK-NEXT:    ret i1 [[OV]]<br>
+; CHECK-NEXT:    [[TMP1:%.*]] = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 42, i8 [[X:%.*]])<br>
+; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i8, i1 } [[TMP1]], 0<br>
+; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1<br>
+; CHECK-NEXT:    store i8 [[MATH]], i8* [[P:%.*]]<br>
+; CHECK-NEXT:    ret i1 [[OV1]]<br>
 ;<br>
   %s = sub i8 42, %x<br>
   %ov = icmp ugt i8 %x, 42<br>
@@ -220,10 +223,11 @@ define i1 @usubo_ugt_constant_op0_i8(i8<br>
<br>
 define i1 @usubo_ult_constant_op0_i16(i16 %x, i16* %p) {<br>
 ; CHECK-LABEL: @usubo_ult_constant_op0_i16(<br>
-; CHECK-NEXT:    [[S:%.*]] = sub i16 43, [[X:%.*]]<br>
-; CHECK-NEXT:    [[OV:%.*]] = icmp ult i16 43, [[X]]<br>
-; CHECK-NEXT:    store i16 [[S]], i16* [[P:%.*]]<br>
-; CHECK-NEXT:    ret i1 [[OV]]<br>
+; CHECK-NEXT:    [[TMP1:%.*]] = call { i16, i1 } @llvm.usub.with.overflow.i16(i16 43, i16 [[X:%.*]])<br>
+; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i16, i1 } [[TMP1]], 0<br>
+; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1<br>
+; CHECK-NEXT:    store i16 [[MATH]], i16* [[P:%.*]]<br>
+; CHECK-NEXT:    ret i1 [[OV1]]<br>
 ;<br>
   %s = sub i16 43, %x<br>
   %ov = icmp ult i16 43, %x<br>
@@ -235,10 +239,11 @@ define i1 @usubo_ult_constant_op0_i16(i1<br>
<br>
 define i1 @usubo_ult_constant_op1_i16(i16 %x, i16* %p) {<br>
 ; CHECK-LABEL: @usubo_ult_constant_op1_i16(<br>
-; CHECK-NEXT:    [[S:%.*]] = add i16 [[X:%.*]], -44<br>
-; CHECK-NEXT:    [[OV:%.*]] = icmp ult i16 [[X]], 44<br>
-; CHECK-NEXT:    store i16 [[S]], i16* [[P:%.*]]<br>
-; CHECK-NEXT:    ret i1 [[OV]]<br>
+; CHECK-NEXT:    [[TMP1:%.*]] = call { i16, i1 } @llvm.usub.with.overflow.i16(i16 [[X:%.*]], i16 44)<br>
+; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i16, i1 } [[TMP1]], 0<br>
+; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1<br>
+; CHECK-NEXT:    store i16 [[MATH]], i16* [[P:%.*]]<br>
+; CHECK-NEXT:    ret i1 [[OV1]]<br>
 ;<br>
   %s = add i16 %x, -44<br>
   %ov = icmp ult i16 %x, 44<br>
@@ -248,10 +253,11 @@ define i1 @usubo_ult_constant_op1_i16(i1<br>
<br>
 define i1 @usubo_ugt_constant_op1_i8(i8 %x, i8* %p) {<br>
 ; CHECK-LABEL: @usubo_ugt_constant_op1_i8(<br>
-; CHECK-NEXT:    [[OV:%.*]] = icmp ugt i8 45, [[X:%.*]]<br>
-; CHECK-NEXT:    [[S:%.*]] = add i8 [[X]], -45<br>
-; CHECK-NEXT:    store i8 [[S]], i8* [[P:%.*]]<br>
-; CHECK-NEXT:    ret i1 [[OV]]<br>
+; CHECK-NEXT:    [[TMP1:%.*]] = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[X:%.*]], i8 45)<br>
+; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i8, i1 } [[TMP1]], 0<br>
+; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1<br>
+; CHECK-NEXT:    store i8 [[MATH]], i8* [[P:%.*]]<br>
+; CHECK-NEXT:    ret i1 [[OV1]]<br>
 ;<br>
   %ov = icmp ugt i8 45, %x<br>
   %s = add i8 %x, -45<br>
@@ -263,10 +269,11 @@ define i1 @usubo_ugt_constant_op1_i8(i8<br>
<br>
 define i1 @usubo_eq_constant1_op1_i32(i32 %x, i32* %p) {<br>
 ; CHECK-LABEL: @usubo_eq_constant1_op1_i32(<br>
-; CHECK-NEXT:    [[S:%.*]] = add i32 [[X:%.*]], -1<br>
-; CHECK-NEXT:    [[OV:%.*]] = icmp eq i32 [[X]], 0<br>
-; CHECK-NEXT:    store i32 [[S]], i32* [[P:%.*]]<br>
-; CHECK-NEXT:    ret i1 [[OV]]<br>
+; CHECK-NEXT:    [[TMP1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[X:%.*]], i32 1)<br>
+; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0<br>
+; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1<br>
+; CHECK-NEXT:    store i32 [[MATH]], i32* [[P:%.*]]<br>
+; CHECK-NEXT:    ret i1 [[OV1]]<br>
 ;<br>
   %s = add i32 %x, -1<br>
   %ov = icmp eq i32 %x, 0<br>
@@ -283,14 +290,15 @@ define i1 @usubo_ult_sub_dominates_i64(i<br>
 ; CHECK-NEXT:  entry:<br>
 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]]<br>
 ; CHECK:       t:<br>
-; CHECK-NEXT:    [[S:%.*]] = sub i64 [[X:%.*]], [[Y:%.*]]<br>
-; CHECK-NEXT:    store i64 [[S]], i64* [[P:%.*]]<br>
+; CHECK-NEXT:    [[TMP0:%.*]] = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 [[X:%.*]], i64 [[Y:%.*]])<br>
+; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP0]], 0<br>
+; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP0]], 1<br>
+; CHECK-NEXT:    store i64 [[MATH]], i64* [[P:%.*]]<br>
 ; CHECK-NEXT:    br i1 [[COND]], label [[END:%.*]], label [[F]]<br>
 ; CHECK:       f:<br>
 ; CHECK-NEXT:    ret i1 [[COND]]<br>
 ; CHECK:       end:<br>
-; CHECK-NEXT:    [[OV:%.*]] = icmp ult i64 [[X]], [[Y]]<br>
-; CHECK-NEXT:    ret i1 [[OV]]<br>
+; CHECK-NEXT:    ret i1 [[OV1]]<br>
 ;<br>
 entry:<br>
   br i1 %cond, label %t, label %f<br>
@@ -319,10 +327,11 @@ define i1 @usubo_ult_cmp_dominates_i64(i<br>
 ; CHECK:       f:<br>
 ; CHECK-NEXT:    ret i1 [[COND]]<br>
 ; CHECK:       end:<br>
-; CHECK-NEXT:    [[TMP0:%.*]] = icmp ult i64 [[X]], [[Y]]<br>
-; CHECK-NEXT:    [[S:%.*]] = sub i64 [[X]], [[Y]]<br>
-; CHECK-NEXT:    store i64 [[S]], i64* [[P:%.*]]<br>
-; CHECK-NEXT:    ret i1 [[TMP0]]<br>
+; CHECK-NEXT:    [[TMP0:%.*]] = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 [[X]], i64 [[Y]])<br>
+; CHECK-NEXT:    [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP0]], 0<br>
+; CHECK-NEXT:    [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP0]], 1<br>
+; CHECK-NEXT:    store i64 [[MATH]], i64* [[P:%.*]]<br>
+; CHECK-NEXT:    ret i1 [[OV1]]<br>
 ;<br>
 entry:<br>
   br i1 %cond, label %t, label %f<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><u></u><u></u></p>
</blockquote>
</div>
<p class="MsoNormal"><br clear="all">
<u></u><u></u></p>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<p class="MsoNormal">-- <u></u><u></u></p>
<div>
<div>
<div>
<table class="gmail-m_1938106320789593845gmail-m_-9122261492763692324MsoNormalTable" cellspacing="0" cellpadding="0" border="0">
<tbody>
<tr>
<td style="border-color:rgb(213,15,37) currentcolor currentcolor;border-style:solid none none;border-width:1.5pt medium medium;padding:0in" nowrap>
<p class="MsoNormal"><span style="font-size:12pt;font-family:"Arial",sans-serif;color:rgb(85,85,85)">Teresa Johnson |<u></u><u></u></span></p>
</td>
<td style="border-color:rgb(51,105,232) currentcolor currentcolor;border-style:solid none none;border-width:1.5pt medium medium;padding:0in" nowrap>
<p class="MsoNormal"><span style="font-size:12pt;font-family:"Arial",sans-serif;color:rgb(85,85,85)"> Software Engineer |<u></u><u></u></span></p>
</td>
<td style="border-color:rgb(0,153,57) currentcolor currentcolor;border-style:solid none none;border-width:1.5pt medium medium;padding:0in" nowrap>
<p class="MsoNormal"><span style="font-size:12pt;font-family:"Arial",sans-serif;color:rgb(85,85,85)"> <a href="mailto:tejohnson@google.com" target="_blank">tejohnson@google.com</a> |<u></u><u></u></span></p>
</td>
<td style="border-color:rgb(238,178,17) currentcolor currentcolor;border-style:solid none none;border-width:1.5pt medium medium;padding:0in" nowrap>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<p class="MsoNormal"><u></u> <u></u></p>
<pre>_______________________________________________<u></u><u></u></pre>
<pre>llvm-commits mailing list<u></u><u></u></pre>
<pre><a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><u></u><u></u></pre>
<pre><a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><u></u><u></u></pre>
</blockquote>
</div>
</blockquote>
</div>
</div>
</div>

</blockquote></div>
</blockquote></div>