diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp index 9bbb89e37865d..ee0f9e8554489 100644 --- a/llvm/lib/CodeGen/CodeGenPrepare.cpp +++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp @@ -470,10 +470,12 @@ class CodeGenPrepare { bool tryToSinkFreeOperands(Instruction *I); bool replaceMathCmpWithIntrinsic(BinaryOperator *BO, Value *Arg0, Value *Arg1, - CmpInst *Cmp, Intrinsic::ID IID); + CmpInst *Cmp, Intrinsic::ID IID, + bool NegateOverflow = false); bool optimizeCmp(CmpInst *Cmp, ModifyDT &ModifiedDT); bool optimizeURem(Instruction *Rem); bool combineToUSubWithOverflow(CmpInst *Cmp, ModifyDT &ModifiedDT); + bool combineToUSubWithNegatedOverflow(CmpInst *Cmp, ModifyDT &ModifiedDT); bool combineToUAddWithOverflow(CmpInst *Cmp, ModifyDT &ModifiedDT); bool unfoldPowerOf2Test(CmpInst *Cmp); void verifyBFIUpdates(Function &F); @@ -1552,7 +1554,8 @@ static bool isIVIncrement(const Value *V, const LoopInfo *LI) { bool CodeGenPrepare::replaceMathCmpWithIntrinsic(BinaryOperator *BO, Value *Arg0, Value *Arg1, CmpInst *Cmp, - Intrinsic::ID IID) { + Intrinsic::ID IID, + bool NegateOverflow) { auto IsReplacableIVIncrement = [this, &Cmp](BinaryOperator *BO) { if (!isIVIncrement(BO, LI)) return false; @@ -1624,6 +1627,8 @@ bool CodeGenPrepare::replaceMathCmpWithIntrinsic(BinaryOperator *BO, assert(BO->hasOneUse() && "Patterns with XOr should use the BO only in the compare"); Value *OV = Builder.CreateExtractValue(MathOV, 1, "ov"); + if (NegateOverflow) + OV = Builder.CreateXor(OV, ConstantInt::getAllOnesValue(OV->getType())); replaceAllUsesWith(Cmp, OV, FreshBBs, IsHugeFunc); Cmp->eraseFromParent(); BO->eraseFromParent(); @@ -1759,6 +1764,71 @@ bool CodeGenPrepare::combineToUSubWithOverflow(CmpInst *Cmp, return true; } +bool CodeGenPrepare::combineToUSubWithNegatedOverflow(CmpInst *Cmp, + ModifyDT &ModifiedDT) { + // We are not expecting non-canonical/degenerate code. Just bail out. + Value *A = Cmp->getOperand(0), *B = Cmp->getOperand(1); + if (isa(A) && isa(B)) + return false; + + // Convert (A u<= B) to (A u>= B) to simplify pattern matching. + ICmpInst::Predicate Pred = Cmp->getPredicate(); + if (Pred == ICmpInst::ICMP_ULE) { + std::swap(A, B); + Pred = ICmpInst::ICMP_UGE; + } + // Convert special-case: (A != 0) is the same as (A u>= 1). + if (Pred == ICmpInst::ICMP_NE && match(B, m_ZeroInt())) { + B = ConstantInt::get(B->getType(), 1); + Pred = ICmpInst::ICMP_UGE; + } + + // Convert special-case: (A == 0) is the same as (0 u>= A). + if (Pred == ICmpInst::ICMP_EQ && match(B, m_ZeroInt())) { + std::swap(A, B); + Pred = ICmpInst::ICMP_UGE; + } + + if (Pred != ICmpInst::ICMP_UGE) + return false; + + // Walk the users of a variable operand of a compare looking for a subtract or + // add with that same operand. Also match the 2nd operand of the compare to + // the add/sub, but that may be a negated constant operand of an add. + Value *CmpVariableOperand = isa(A) ? B : A; + BinaryOperator *Sub = nullptr; + for (User *U : CmpVariableOperand->users()) { + // A - B, A u> B --> usubo(A, B) + if (match(U, m_Sub(m_Specific(A), m_Specific(B)))) { + Sub = cast(U); + break; + } + + // A + (-C), A u> C (canonicalized form of (sub A, C)) + const APInt *CmpC, *AddC; + if (match(U, m_Add(m_Specific(A), m_APInt(AddC))) && + match(B, m_APInt(CmpC)) && *AddC == -(*CmpC)) { + Sub = cast(U); + break; + } + } + if (!Sub) + return false; + + if (!TLI->shouldFormOverflowOp(ISD::USUBO, + TLI->getValueType(*DL, Sub->getType()), + Sub->hasNUsesOrMore(1))) + return false; + + if (!replaceMathCmpWithIntrinsic(Sub, Sub->getOperand(0), Sub->getOperand(1), + Cmp, Intrinsic::usub_with_overflow, true)) + return false; + + // Reset callers - do not crash by iterating over a dead instruction. + ModifiedDT = ModifyDT::ModifyInstDT; + return true; +} + // Decanonicalizes icmp+ctpop power-of-two test if ctpop is slow. // The same transformation exists in DAG combiner, but we repeat it here because // DAG builder can break the pattern by moving icmp into a successor block. @@ -2224,6 +2294,9 @@ bool CodeGenPrepare::optimizeCmp(CmpInst *Cmp, ModifyDT &ModifiedDT) { if (combineToUSubWithOverflow(Cmp, ModifiedDT)) return true; + if (combineToUSubWithNegatedOverflow(Cmp, ModifiedDT)) + return true; + if (unfoldPowerOf2Test(Cmp)) return true; diff --git a/llvm/test/CodeGen/X86/abdu-neg.ll b/llvm/test/CodeGen/X86/abdu-neg.ll index 6bda99c89a37e..59b36577540b7 100644 --- a/llvm/test/CodeGen/X86/abdu-neg.ll +++ b/llvm/test/CodeGen/X86/abdu-neg.ll @@ -719,8 +719,8 @@ define i8 @abd_cmp_i8(i8 %a, i8 %b) nounwind { ; ; X64-LABEL: abd_cmp_i8: ; X64: # %bb.0: -; X64-NEXT: movzbl %sil, %eax -; X64-NEXT: movzbl %dil, %ecx +; X64-NEXT: movzbl %dil, %eax +; X64-NEXT: movzbl %sil, %ecx ; X64-NEXT: movl %ecx, %edx ; X64-NEXT: subl %eax, %edx ; X64-NEXT: subl %ecx, %eax diff --git a/llvm/test/CodeGen/X86/atomicrmw-cond-sub-clamp.ll b/llvm/test/CodeGen/X86/atomicrmw-cond-sub-clamp.ll index 3e1a631e39b06..db1dbd45d10b6 100644 --- a/llvm/test/CodeGen/X86/atomicrmw-cond-sub-clamp.ll +++ b/llvm/test/CodeGen/X86/atomicrmw-cond-sub-clamp.ll @@ -16,12 +16,13 @@ define i8 @atomicrmw_usub_cond_i8(ptr %ptr, i8 %val) { ; CHECK-32-NEXT: je .LBB0_4 ; CHECK-32-NEXT: .LBB0_1: # %atomicrmw.start ; CHECK-32-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-32-NEXT: movb %al, %ch +; CHECK-32-NEXT: subb %cl, %ch ; CHECK-32-NEXT: movb %al, %ah -; CHECK-32-NEXT: subb %cl, %ah -; CHECK-32-NEXT: jae .LBB0_3 +; CHECK-32-NEXT: jb .LBB0_3 ; CHECK-32-NEXT: # %bb.2: # %atomicrmw.start ; CHECK-32-NEXT: # in Loop: Header=BB0_1 Depth=1 -; CHECK-32-NEXT: movb %al, %ah +; CHECK-32-NEXT: movb %ch, %ah ; CHECK-32-NEXT: jmp .LBB0_3 ; CHECK-32-NEXT: .LBB0_4: # %atomicrmw.end ; CHECK-32-NEXT: retl @@ -67,8 +68,7 @@ define i16 @atomicrmw_usub_cond_i16(ptr %ptr, i16 %val) { ; CHECK-32-NEXT: movl %eax, %esi ; CHECK-32-NEXT: subw %cx, %si ; CHECK-32-NEXT: jae .LBB1_3 -; CHECK-32-NEXT: # %bb.2: # %atomicrmw.start -; CHECK-32-NEXT: # in Loop: Header=BB1_1 Depth=1 +; CHECK-32-NEXT: # %bb.2: # in Loop: Header=BB1_1 Depth=1 ; CHECK-32-NEXT: movl %eax, %esi ; CHECK-32-NEXT: jmp .LBB1_3 ; CHECK-32-NEXT: .LBB1_4: # %atomicrmw.end @@ -100,9 +100,12 @@ define i16 @atomicrmw_usub_cond_i16(ptr %ptr, i16 %val) { define i32 @atomicrmw_usub_cond_i32(ptr %ptr, i32 %val) { ; CHECK-32-LABEL: atomicrmw_usub_cond_i32: ; CHECK-32: # %bb.0: -; CHECK-32-NEXT: pushl %esi +; CHECK-32-NEXT: pushl %edi ; CHECK-32-NEXT: .cfi_def_cfa_offset 8 -; CHECK-32-NEXT: .cfi_offset %esi, -8 +; CHECK-32-NEXT: pushl %esi +; CHECK-32-NEXT: .cfi_def_cfa_offset 12 +; CHECK-32-NEXT: .cfi_offset %esi, -12 +; CHECK-32-NEXT: .cfi_offset %edi, -8 ; CHECK-32-NEXT: movl {{[0-9]+}}(%esp), %ecx ; CHECK-32-NEXT: movl {{[0-9]+}}(%esp), %edx ; CHECK-32-NEXT: movl (%edx), %eax @@ -114,15 +117,18 @@ define i32 @atomicrmw_usub_cond_i32(ptr %ptr, i32 %val) { ; CHECK-32-NEXT: je .LBB2_4 ; CHECK-32-NEXT: .LBB2_1: # %atomicrmw.start ; CHECK-32-NEXT: # =>This Inner Loop Header: Depth=1 +; CHECK-32-NEXT: movl %eax, %edi +; CHECK-32-NEXT: subl %ecx, %edi ; CHECK-32-NEXT: movl %eax, %esi -; CHECK-32-NEXT: subl %ecx, %esi -; CHECK-32-NEXT: jae .LBB2_3 +; CHECK-32-NEXT: jb .LBB2_3 ; CHECK-32-NEXT: # %bb.2: # %atomicrmw.start ; CHECK-32-NEXT: # in Loop: Header=BB2_1 Depth=1 -; CHECK-32-NEXT: movl %eax, %esi +; CHECK-32-NEXT: movl %edi, %esi ; CHECK-32-NEXT: jmp .LBB2_3 ; CHECK-32-NEXT: .LBB2_4: # %atomicrmw.end ; CHECK-32-NEXT: popl %esi +; CHECK-32-NEXT: .cfi_def_cfa_offset 8 +; CHECK-32-NEXT: popl %edi ; CHECK-32-NEXT: .cfi_def_cfa_offset 4 ; CHECK-32-NEXT: retl ; @@ -158,30 +164,35 @@ define i64 @atomicrmw_usub_cond_i64(ptr %ptr, i64 %val) { ; CHECK-32-NEXT: .cfi_offset %edi, -16 ; CHECK-32-NEXT: .cfi_offset %ebx, -12 ; CHECK-32-NEXT: .cfi_offset %ebp, -8 -; CHECK-32-NEXT: movl {{[0-9]+}}(%esp), %esi -; CHECK-32-NEXT: movl {{[0-9]+}}(%esp), %edi ; CHECK-32-NEXT: movl {{[0-9]+}}(%esp), %ebp ; CHECK-32-NEXT: movl (%ebp), %eax -; CHECK-32-NEXT: movl 4(%ebp), %edx +; CHECK-32-NEXT: movl 4(%ebp), %ecx ; CHECK-32-NEXT: jmp .LBB3_1 ; CHECK-32-NEXT: .p2align 4 ; CHECK-32-NEXT: .LBB3_3: # %atomicrmw.start ; CHECK-32-NEXT: # in Loop: Header=BB3_1 Depth=1 +; CHECK-32-NEXT: movl %ecx, %edx +; CHECK-32-NEXT: movl %edi, %ecx +; CHECK-32-NEXT: movl %esi, %ebx ; CHECK-32-NEXT: lock cmpxchg8b (%ebp) +; CHECK-32-NEXT: movl %edx, %ecx ; CHECK-32-NEXT: je .LBB3_4 ; CHECK-32-NEXT: .LBB3_1: # %atomicrmw.start ; CHECK-32-NEXT: # =>This Inner Loop Header: Depth=1 ; CHECK-32-NEXT: movl %eax, %ebx -; CHECK-32-NEXT: subl %edi, %ebx -; CHECK-32-NEXT: movl %edx, %ecx -; CHECK-32-NEXT: sbbl %esi, %ecx -; CHECK-32-NEXT: jae .LBB3_3 +; CHECK-32-NEXT: subl {{[0-9]+}}(%esp), %ebx +; CHECK-32-NEXT: movl %ecx, %edx +; CHECK-32-NEXT: sbbl {{[0-9]+}}(%esp), %edx +; CHECK-32-NEXT: movl %ecx, %edi +; CHECK-32-NEXT: movl %eax, %esi +; CHECK-32-NEXT: jb .LBB3_3 ; CHECK-32-NEXT: # %bb.2: # %atomicrmw.start ; CHECK-32-NEXT: # in Loop: Header=BB3_1 Depth=1 -; CHECK-32-NEXT: movl %edx, %ecx -; CHECK-32-NEXT: movl %eax, %ebx +; CHECK-32-NEXT: movl %edx, %edi +; CHECK-32-NEXT: movl %ebx, %esi ; CHECK-32-NEXT: jmp .LBB3_3 ; CHECK-32-NEXT: .LBB3_4: # %atomicrmw.end +; CHECK-32-NEXT: movl %ecx, %edx ; CHECK-32-NEXT: popl %esi ; CHECK-32-NEXT: .cfi_def_cfa_offset 16 ; CHECK-32-NEXT: popl %edi diff --git a/llvm/test/CodeGen/X86/bmi.ll b/llvm/test/CodeGen/X86/bmi.ll index 2683fab59ad1b..50d32cf80b364 100644 --- a/llvm/test/CodeGen/X86/bmi.ll +++ b/llvm/test/CodeGen/X86/bmi.ll @@ -1948,27 +1948,35 @@ define void @pr42118_i64(i64 %x) { define i32 @blsi_cflag_32(i32 %x, i32 %y) nounwind { ; X86-LABEL: blsi_cflag_32: ; X86: # %bb.0: -; X86-NEXT: movl {{[0-9]+}}(%esp), %eax -; X86-NEXT: testl %eax, %eax -; X86-NEXT: jne .LBB59_1 +; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-NEXT: movl %ecx, %eax +; X86-NEXT: negl %eax +; X86-NEXT: movl %ecx, %edx +; X86-NEXT: negl %edx +; X86-NEXT: jb .LBB59_1 ; X86-NEXT: # %bb.2: ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax ; X86-NEXT: retl ; X86-NEXT: .LBB59_1: -; X86-NEXT: blsil %eax, %eax +; X86-NEXT: andl %ecx, %eax ; X86-NEXT: retl ; ; X64-LABEL: blsi_cflag_32: ; X64: # %bb.0: -; X64-NEXT: blsil %edi, %eax +; X64-NEXT: movl %edi, %eax +; X64-NEXT: negl %eax +; X64-NEXT: andl %edi, %eax +; X64-NEXT: negl %edi ; X64-NEXT: cmovael %esi, %eax ; X64-NEXT: retq ; ; EGPR-LABEL: blsi_cflag_32: ; EGPR: # %bb.0: -; EGPR-NEXT: blsil %edi, %eax # EVEX TO VEX Compression encoding: [0xc4,0xe2,0x78,0xf3,0xdf] -; EGPR-NEXT: testl %edi, %edi # encoding: [0x85,0xff] -; EGPR-NEXT: cmovel %esi, %eax # encoding: [0x0f,0x44,0xc6] +; EGPR-NEXT: movl %edi, %eax # encoding: [0x89,0xf8] +; EGPR-NEXT: negl %eax # encoding: [0xf7,0xd8] +; EGPR-NEXT: andl %edi, %eax # encoding: [0x21,0xf8] +; EGPR-NEXT: negl %edi # encoding: [0xf7,0xdf] +; EGPR-NEXT: cmovael %esi, %eax # encoding: [0x0f,0x43,0xc6] ; EGPR-NEXT: retq # encoding: [0xc3] %tobool = icmp eq i32 %x, 0 %sub = sub nsw i32 0, %x @@ -1980,40 +1988,54 @@ define i32 @blsi_cflag_32(i32 %x, i32 %y) nounwind { define i64 @blsi_cflag_64(i64 %x, i64 %y) nounwind { ; X86-LABEL: blsi_cflag_64: ; X86: # %bb.0: +; X86-NEXT: pushl %ebx ; X86-NEXT: pushl %edi ; X86-NEXT: pushl %esi -; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx ; X86-NEXT: movl {{[0-9]+}}(%esp), %esi -; X86-NEXT: xorl %edx, %edx -; X86-NEXT: movl %ecx, %eax +; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-NEXT: movl %esi, %eax ; X86-NEXT: negl %eax -; X86-NEXT: sbbl %esi, %edx -; X86-NEXT: movl %ecx, %edi -; X86-NEXT: orl %esi, %edi -; X86-NEXT: jne .LBB60_1 +; X86-NEXT: xorl %edx, %edx +; X86-NEXT: movl %esi, %edi +; X86-NEXT: negl %edi +; X86-NEXT: sbbl %ecx, %edx +; X86-NEXT: setae %bl +; X86-NEXT: jb .LBB60_1 ; X86-NEXT: # %bb.2: -; X86-NEXT: movl {{[0-9]+}}(%esp), %edx ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax -; X86-NEXT: jmp .LBB60_3 +; X86-NEXT: testb %bl, %bl +; X86-NEXT: jne .LBB60_5 +; X86-NEXT: .LBB60_4: +; X86-NEXT: andl %ecx, %edx +; X86-NEXT: jmp .LBB60_6 ; X86-NEXT: .LBB60_1: -; X86-NEXT: andl %esi, %edx -; X86-NEXT: andl %ecx, %eax -; X86-NEXT: .LBB60_3: +; X86-NEXT: andl %esi, %eax +; X86-NEXT: testb %bl, %bl +; X86-NEXT: je .LBB60_4 +; X86-NEXT: .LBB60_5: +; X86-NEXT: movl {{[0-9]+}}(%esp), %edx +; X86-NEXT: .LBB60_6: ; X86-NEXT: popl %esi ; X86-NEXT: popl %edi +; X86-NEXT: popl %ebx ; X86-NEXT: retl ; ; X64-LABEL: blsi_cflag_64: ; X64: # %bb.0: -; X64-NEXT: blsiq %rdi, %rax +; X64-NEXT: movq %rdi, %rax +; X64-NEXT: negq %rax +; X64-NEXT: andq %rdi, %rax +; X64-NEXT: negq %rdi ; X64-NEXT: cmovaeq %rsi, %rax ; X64-NEXT: retq ; ; EGPR-LABEL: blsi_cflag_64: ; EGPR: # %bb.0: -; EGPR-NEXT: blsiq %rdi, %rax # EVEX TO VEX Compression encoding: [0xc4,0xe2,0xf8,0xf3,0xdf] -; EGPR-NEXT: testq %rdi, %rdi # encoding: [0x48,0x85,0xff] -; EGPR-NEXT: cmoveq %rsi, %rax # encoding: [0x48,0x0f,0x44,0xc6] +; EGPR-NEXT: movq %rdi, %rax # encoding: [0x48,0x89,0xf8] +; EGPR-NEXT: negq %rax # encoding: [0x48,0xf7,0xd8] +; EGPR-NEXT: andq %rdi, %rax # encoding: [0x48,0x21,0xf8] +; EGPR-NEXT: negq %rdi # encoding: [0x48,0xf7,0xdf] +; EGPR-NEXT: cmovaeq %rsi, %rax # encoding: [0x48,0x0f,0x43,0xc6] ; EGPR-NEXT: retq # encoding: [0xc3] %tobool = icmp eq i64 %x, 0 %sub = sub nsw i64 0, %x diff --git a/llvm/test/CodeGen/X86/sub-with-overflow.ll b/llvm/test/CodeGen/X86/sub-with-overflow.ll index d3bd3b1cdf0ac..3aa1c8e217ac8 100644 --- a/llvm/test/CodeGen/X86/sub-with-overflow.ll +++ b/llvm/test/CodeGen/X86/sub-with-overflow.ll @@ -93,3 +93,82 @@ entry: ret i1 %obit } + +define i1 @usubo_uge_i64_overflow_used(i64 %x, i64 %y, ptr %p) { +; CHECK-LABEL: usubo_uge_i64_overflow_used: +; CHECK: # %bb.0: +; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax +; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx +; CHECK-NEXT: cmpl {{[0-9]+}}(%esp), %eax +; CHECK-NEXT: sbbl {{[0-9]+}}(%esp), %ecx +; CHECK-NEXT: setae %al +; CHECK-NEXT: retl + %s = sub i64 %x, %y + %ov = icmp uge i64 %x, %y + ret i1 %ov +} + +define i1 @usubo_uge_i64_math_overflow_used(i64 %x, i64 %y, ptr %p) { +; CHECK-LABEL: usubo_uge_i64_math_overflow_used: +; CHECK: # %bb.0: +; CHECK-NEXT: pushl %esi +; CHECK-NEXT: .cfi_def_cfa_offset 8 +; CHECK-NEXT: .cfi_offset %esi, -8 +; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx +; CHECK-NEXT: movl {{[0-9]+}}(%esp), %edx +; CHECK-NEXT: movl {{[0-9]+}}(%esp), %esi +; CHECK-NEXT: subl {{[0-9]+}}(%esp), %edx +; CHECK-NEXT: sbbl {{[0-9]+}}(%esp), %esi +; CHECK-NEXT: setae %al +; CHECK-NEXT: movl %edx, (%ecx) +; CHECK-NEXT: movl %esi, 4(%ecx) +; CHECK-NEXT: popl %esi +; CHECK-NEXT: .cfi_def_cfa_offset 4 +; CHECK-NEXT: retl + %s = sub i64 %x, %y + store i64 %s, ptr %p + %ov = icmp uge i64 %x, %y + ret i1 %ov +} + +define i1 @usubo_ule_i32_overflow_used(i32 %x, i32 %y, ptr %p) { +; CHECK-LABEL: usubo_ule_i32_overflow_used: +; CHECK: # %bb.0: +; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax +; CHECK-NEXT: cmpl {{[0-9]+}}(%esp), %eax +; CHECK-NEXT: setae %al +; CHECK-NEXT: retl + %s = sub i32 %y, %x + %ov = icmp ule i32 %x, %y + ret i1 %ov +} + +define i1 @usubo_ne_zero_i16_overflow_used(i16 %x, ptr %p) { +; CHECK-LABEL: usubo_ne_zero_i16_overflow_used: +; CHECK: # %bb.0: +; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx +; CHECK-NEXT: movzwl {{[0-9]+}}(%esp), %edx +; CHECK-NEXT: subw $1, %dx +; CHECK-NEXT: setae %al +; CHECK-NEXT: movw %dx, (%ecx) +; CHECK-NEXT: retl + %s = sub i16 %x, 1 + store i16 %s, ptr %p + %ov = icmp ne i16 %x, 0 + ret i1 %ov +} + +define i1 @usubo_eq_zero_i8_overflow_used(i8 %x, ptr %p) { +; CHECK-LABEL: usubo_eq_zero_i8_overflow_used: +; CHECK: # %bb.0: +; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx +; CHECK-NEXT: xorl %edx, %edx +; CHECK-NEXT: subb {{[0-9]+}}(%esp), %dl +; CHECK-NEXT: setae %al +; CHECK-NEXT: movb %dl, (%ecx) +; CHECK-NEXT: retl + %s = sub i8 0, %x + store i8 %s, ptr %p + %ov = icmp eq i8 %x, 0 + ret i1 %ov +} diff --git a/llvm/test/Transforms/CodeGenPrepare/X86/overflow-intrinsics.ll b/llvm/test/Transforms/CodeGenPrepare/X86/overflow-intrinsics.ll index 653f346356488..e6c99b32ea0dd 100644 --- a/llvm/test/Transforms/CodeGenPrepare/X86/overflow-intrinsics.ll +++ b/llvm/test/Transforms/CodeGenPrepare/X86/overflow-intrinsics.ll @@ -12,6 +12,16 @@ define i64 @uaddo1_overflow_used(i64 %a, i64 %b) nounwind ssp { ; CHECK-NEXT: [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1 ; CHECK-NEXT: [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42 ; CHECK-NEXT: ret i64 [[Q]] +; +; DEBUG-LABEL: @uaddo1_overflow_used( +; DEBUG-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[B:%.*]], i64 [[A:%.*]]), !dbg [[DBG14:![0-9]+]] +; DEBUG-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0, !dbg [[DBG14]] +; DEBUG-NEXT: [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !dbg [[DBG14]] +; DEBUG-NEXT: #dbg_value(i64 [[MATH]], [[META9:![0-9]+]], !DIExpression(), [[DBG14]]) +; DEBUG-NEXT: #dbg_value(i1 [[OV]], [[META11:![0-9]+]], !DIExpression(), [[META15:![0-9]+]]) +; DEBUG-NEXT: [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42, !dbg [[DBG16:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i64 [[Q]], [[META13:![0-9]+]], !DIExpression(), [[DBG16]]) +; DEBUG-NEXT: ret i64 [[Q]], !dbg [[DBG17:![0-9]+]] ; %add = add i64 %b, %a %cmp = icmp ult i64 %add, %a @@ -25,8 +35,19 @@ define i64 @uaddo1_math_overflow_used(i64 %a, i64 %b, ptr %res) nounwind ssp { ; 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: store i64 [[MATH]], ptr [[RES:%.*]] +; CHECK-NEXT: store i64 [[MATH]], ptr [[RES:%.*]], align 8 ; CHECK-NEXT: ret i64 [[Q]] +; +; DEBUG-LABEL: @uaddo1_math_overflow_used( +; DEBUG-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[B:%.*]], i64 [[A:%.*]]), !dbg [[DBG23:![0-9]+]] +; DEBUG-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0, !dbg [[DBG23]] +; DEBUG-NEXT: [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !dbg [[DBG23]] +; DEBUG-NEXT: #dbg_value(i64 [[MATH]], [[META20:![0-9]+]], !DIExpression(), [[DBG23]]) +; DEBUG-NEXT: #dbg_value(i1 [[OV]], [[META21:![0-9]+]], !DIExpression(), [[META24:![0-9]+]]) +; DEBUG-NEXT: [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42, !dbg [[DBG25:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i64 [[Q]], [[META22:![0-9]+]], !DIExpression(), [[DBG25]]) +; DEBUG-NEXT: store i64 [[MATH]], ptr [[RES:%.*]], align 8, !dbg [[DBG26:![0-9]+]] +; DEBUG-NEXT: ret i64 [[Q]], !dbg [[DBG27:![0-9]+]] ; %add = add i64 %b, %a %cmp = icmp ult i64 %add, %a @@ -42,6 +63,16 @@ define i64 @uaddo2_overflow_used(i64 %a, i64 %b) nounwind ssp { ; CHECK-NEXT: [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1 ; CHECK-NEXT: [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42 ; CHECK-NEXT: ret i64 [[Q]] +; +; DEBUG-LABEL: @uaddo2_overflow_used( +; DEBUG-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[B:%.*]], i64 [[A:%.*]]), !dbg [[DBG33:![0-9]+]] +; DEBUG-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0, !dbg [[DBG33]] +; DEBUG-NEXT: [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !dbg [[DBG33]] +; DEBUG-NEXT: #dbg_value(i64 [[MATH]], [[META30:![0-9]+]], !DIExpression(), [[DBG33]]) +; DEBUG-NEXT: #dbg_value(i1 [[OV]], [[META31:![0-9]+]], !DIExpression(), [[META34:![0-9]+]]) +; DEBUG-NEXT: [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42, !dbg [[DBG35:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i64 [[Q]], [[META32:![0-9]+]], !DIExpression(), [[DBG35]]) +; DEBUG-NEXT: ret i64 [[Q]], !dbg [[DBG36:![0-9]+]] ; %add = add i64 %b, %a %cmp = icmp ult i64 %add, %b @@ -55,8 +86,19 @@ define i64 @uaddo2_math_overflow_used(i64 %a, i64 %b, ptr %res) nounwind ssp { ; 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: store i64 [[MATH]], ptr [[RES:%.*]] +; CHECK-NEXT: store i64 [[MATH]], ptr [[RES:%.*]], align 8 ; CHECK-NEXT: ret i64 [[Q]] +; +; DEBUG-LABEL: @uaddo2_math_overflow_used( +; DEBUG-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[B:%.*]], i64 [[A:%.*]]), !dbg [[DBG42:![0-9]+]] +; DEBUG-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0, !dbg [[DBG42]] +; DEBUG-NEXT: [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !dbg [[DBG42]] +; DEBUG-NEXT: #dbg_value(i64 [[MATH]], [[META39:![0-9]+]], !DIExpression(), [[DBG42]]) +; DEBUG-NEXT: #dbg_value(i1 [[OV]], [[META40:![0-9]+]], !DIExpression(), [[META43:![0-9]+]]) +; DEBUG-NEXT: [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42, !dbg [[DBG44:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i64 [[Q]], [[META41:![0-9]+]], !DIExpression(), [[DBG44]]) +; DEBUG-NEXT: store i64 [[MATH]], ptr [[RES:%.*]], align 8, !dbg [[DBG45:![0-9]+]] +; DEBUG-NEXT: ret i64 [[Q]], !dbg [[DBG46:![0-9]+]] ; %add = add i64 %b, %a %cmp = icmp ult i64 %add, %b @@ -72,6 +114,16 @@ define i64 @uaddo3_overflow_used(i64 %a, i64 %b) nounwind ssp { ; CHECK-NEXT: [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1 ; CHECK-NEXT: [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42 ; CHECK-NEXT: ret i64 [[Q]] +; +; DEBUG-LABEL: @uaddo3_overflow_used( +; DEBUG-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[B:%.*]], i64 [[A:%.*]]), !dbg [[DBG52:![0-9]+]] +; DEBUG-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0, !dbg [[DBG52]] +; DEBUG-NEXT: [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !dbg [[DBG52]] +; DEBUG-NEXT: #dbg_value(i64 [[MATH]], [[META49:![0-9]+]], !DIExpression(), [[DBG52]]) +; DEBUG-NEXT: #dbg_value(i1 [[OV]], [[META50:![0-9]+]], !DIExpression(), [[META53:![0-9]+]]) +; DEBUG-NEXT: [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42, !dbg [[DBG54:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i64 [[Q]], [[META51:![0-9]+]], !DIExpression(), [[DBG54]]) +; DEBUG-NEXT: ret i64 [[Q]], !dbg [[DBG55:![0-9]+]] ; %add = add i64 %b, %a %cmp = icmp ugt i64 %b, %add @@ -85,8 +137,19 @@ define i64 @uaddo3_math_overflow_used(i64 %a, i64 %b, ptr %res) nounwind ssp { ; 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: store i64 [[MATH]], ptr [[RES:%.*]] +; CHECK-NEXT: store i64 [[MATH]], ptr [[RES:%.*]], align 8 ; CHECK-NEXT: ret i64 [[Q]] +; +; DEBUG-LABEL: @uaddo3_math_overflow_used( +; DEBUG-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[B:%.*]], i64 [[A:%.*]]), !dbg [[DBG61:![0-9]+]] +; DEBUG-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0, !dbg [[DBG61]] +; DEBUG-NEXT: [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !dbg [[DBG61]] +; DEBUG-NEXT: #dbg_value(i64 [[MATH]], [[META58:![0-9]+]], !DIExpression(), [[DBG61]]) +; DEBUG-NEXT: #dbg_value(i1 [[OV]], [[META59:![0-9]+]], !DIExpression(), [[META62:![0-9]+]]) +; DEBUG-NEXT: [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42, !dbg [[DBG63:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i64 [[Q]], [[META60:![0-9]+]], !DIExpression(), [[DBG63]]) +; DEBUG-NEXT: store i64 [[MATH]], ptr [[RES:%.*]], align 8, !dbg [[DBG64:![0-9]+]] +; DEBUG-NEXT: ret i64 [[Q]], !dbg [[DBG65:![0-9]+]] ; %add = add i64 %b, %a %cmp = icmp ugt i64 %b, %add @@ -109,6 +172,20 @@ define i64 @uaddo4(i64 %a, i64 %b, i1 %c) nounwind ssp { ; CHECK: exit: ; CHECK-NEXT: ret i64 0 ; +; DEBUG-LABEL: @uaddo4( +; DEBUG-NEXT: entry: +; DEBUG-NEXT: [[ADD:%.*]] = add i64 [[B:%.*]], [[A:%.*]], !dbg [[DBG71:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i64 [[ADD]], [[META68:![0-9]+]], !DIExpression(), [[DBG71]]) +; DEBUG-NEXT: #dbg_value(i1 poison, [[META69:![0-9]+]], !DIExpression(), [[META72:![0-9]+]]) +; DEBUG-NEXT: br i1 [[C:%.*]], label [[NEXT:%.*]], label [[EXIT:%.*]], !dbg [[DBG73:![0-9]+]] +; DEBUG: next: +; DEBUG-NEXT: [[TMP0:%.*]] = icmp ugt i64 [[B]], [[ADD]], !dbg [[META72]] +; DEBUG-NEXT: [[Q:%.*]] = select i1 [[TMP0]], i64 [[B]], i64 42, !dbg [[DBG74:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i64 [[Q]], [[META70:![0-9]+]], !DIExpression(), [[DBG74]]) +; DEBUG-NEXT: ret i64 [[Q]], !dbg [[DBG75:![0-9]+]] +; DEBUG: exit: +; DEBUG-NEXT: ret i64 0, !dbg [[DBG76:![0-9]+]] +; entry: %add = add i64 %b, %a %cmp = icmp ugt i64 %b, %add @@ -126,7 +203,7 @@ define i64 @uaddo5(i64 %a, i64 %b, ptr %ptr, i1 %c) nounwind ssp { ; CHECK-LABEL: @uaddo5( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[ADD:%.*]] = add i64 [[B:%.*]], [[A:%.*]] -; CHECK-NEXT: store i64 [[ADD]], ptr [[PTR:%.*]] +; CHECK-NEXT: store i64 [[ADD]], ptr [[PTR:%.*]], align 8 ; CHECK-NEXT: br i1 [[C:%.*]], label [[NEXT:%.*]], label [[EXIT:%.*]] ; CHECK: next: ; CHECK-NEXT: [[TMP0:%.*]] = icmp ugt i64 [[B]], [[ADD]] @@ -135,6 +212,21 @@ define i64 @uaddo5(i64 %a, i64 %b, ptr %ptr, i1 %c) nounwind ssp { ; CHECK: exit: ; CHECK-NEXT: ret i64 0 ; +; DEBUG-LABEL: @uaddo5( +; DEBUG-NEXT: entry: +; DEBUG-NEXT: [[ADD:%.*]] = add i64 [[B:%.*]], [[A:%.*]], !dbg [[DBG82:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i64 [[ADD]], [[META79:![0-9]+]], !DIExpression(), [[DBG82]]) +; DEBUG-NEXT: store i64 [[ADD]], ptr [[PTR:%.*]], align 8, !dbg [[DBG83:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i1 poison, [[META80:![0-9]+]], !DIExpression(), [[META84:![0-9]+]]) +; DEBUG-NEXT: br i1 [[C:%.*]], label [[NEXT:%.*]], label [[EXIT:%.*]], !dbg [[DBG85:![0-9]+]] +; DEBUG: next: +; DEBUG-NEXT: [[TMP0:%.*]] = icmp ugt i64 [[B]], [[ADD]], !dbg [[META84]] +; DEBUG-NEXT: [[Q:%.*]] = select i1 [[TMP0]], i64 [[B]], i64 42, !dbg [[DBG86:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i64 [[Q]], [[META81:![0-9]+]], !DIExpression(), [[DBG86]]) +; DEBUG-NEXT: ret i64 [[Q]], !dbg [[DBG87:![0-9]+]] +; DEBUG: exit: +; DEBUG-NEXT: ret i64 0, !dbg [[DBG88:![0-9]+]] +; entry: %add = add i64 %b, %a store i64 %add, ptr %ptr @@ -157,6 +249,15 @@ define i64 @uaddo6_xor(i64 %a, i64 %b) { ; CHECK-NEXT: [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1 ; CHECK-NEXT: [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42 ; CHECK-NEXT: ret i64 [[Q]] +; +; DEBUG-LABEL: @uaddo6_xor( +; DEBUG-NEXT: #dbg_value(i64 poison, [[META91:![0-9]+]], !DIExpression(), [[META94:![0-9]+]]) +; DEBUG-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[A:%.*]], i64 [[B:%.*]]), !dbg [[DBG95:![0-9]+]] +; DEBUG-NEXT: [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !dbg [[DBG95]] +; DEBUG-NEXT: #dbg_value(i1 [[OV]], [[META92:![0-9]+]], !DIExpression(), [[DBG95]]) +; DEBUG-NEXT: [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42, !dbg [[DBG96:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i64 [[Q]], [[META93:![0-9]+]], !DIExpression(), [[DBG96]]) +; DEBUG-NEXT: ret i64 [[Q]], !dbg [[DBG97:![0-9]+]] ; %x = xor i64 %a, -1 %cmp = icmp ult i64 %x, %b @@ -170,6 +271,15 @@ define i64 @uaddo6_xor_commuted(i64 %a, i64 %b) { ; CHECK-NEXT: [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1 ; CHECK-NEXT: [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42 ; CHECK-NEXT: ret i64 [[Q]] +; +; DEBUG-LABEL: @uaddo6_xor_commuted( +; DEBUG-NEXT: #dbg_value(i64 poison, [[META100:![0-9]+]], !DIExpression(), [[META103:![0-9]+]]) +; DEBUG-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[A:%.*]], i64 [[B:%.*]]), !dbg [[DBG104:![0-9]+]] +; DEBUG-NEXT: [[OV:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !dbg [[DBG104]] +; DEBUG-NEXT: #dbg_value(i1 [[OV]], [[META101:![0-9]+]], !DIExpression(), [[DBG104]]) +; DEBUG-NEXT: [[Q:%.*]] = select i1 [[OV]], i64 [[B]], i64 42, !dbg [[DBG105:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i64 [[Q]], [[META102:![0-9]+]], !DIExpression(), [[DBG105]]) +; DEBUG-NEXT: ret i64 [[Q]], !dbg [[DBG106:![0-9]+]] ; %x = xor i64 %a, -1 %cmp = icmp ult i64 %x, %b @@ -186,6 +296,16 @@ define i64 @uaddo6_xor_multi_use(i64 %a, i64 %b) { ; CHECK-NEXT: [[Q:%.*]] = select i1 [[CMP]], i64 [[B]], i64 42 ; CHECK-NEXT: call void @use(i64 [[X]]) ; CHECK-NEXT: ret i64 [[Q]] +; +; DEBUG-LABEL: @uaddo6_xor_multi_use( +; DEBUG-NEXT: [[X:%.*]] = xor i64 -1, [[A:%.*]], !dbg [[DBG112:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i64 [[X]], [[META109:![0-9]+]], !DIExpression(), [[DBG112]]) +; DEBUG-NEXT: [[CMP:%.*]] = icmp ult i64 [[X]], [[B:%.*]], !dbg [[DBG113:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i1 [[CMP]], [[META110:![0-9]+]], !DIExpression(), [[DBG113]]) +; DEBUG-NEXT: [[Q:%.*]] = select i1 [[CMP]], i64 [[B]], i64 42, !dbg [[DBG114:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i64 [[Q]], [[META111:![0-9]+]], !DIExpression(), [[DBG114]]) +; DEBUG-NEXT: call void @use(i64 [[X]]), !dbg [[DBG115:![0-9]+]] +; DEBUG-NEXT: ret i64 [[Q]], !dbg [[DBG116:![0-9]+]] ; %x = xor i64 -1, %a %cmp = icmp ult i64 %x, %b @@ -203,6 +323,17 @@ define i1 @uaddo6_xor_op_after_XOR(i32 %a, ptr %b.ptr) { ; CHECK-NEXT: [[OV1:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1 ; CHECK-NEXT: [[OV:%.*]] = xor i1 [[OV1]], true ; CHECK-NEXT: ret i1 [[OV]] +; +; DEBUG-LABEL: @uaddo6_xor_op_after_XOR( +; DEBUG-NEXT: #dbg_value(i32 poison, [[META119:![0-9]+]], !DIExpression(), [[META124:![0-9]+]]) +; DEBUG-NEXT: [[B:%.*]] = load i32, ptr [[B_PTR:%.*]], align 8, !dbg [[DBG125:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i32 [[B]], [[META121:![0-9]+]], !DIExpression(), [[DBG125]]) +; DEBUG-NEXT: [[TMP1:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[A:%.*]], i32 [[B]]), !dbg [[DBG126:![0-9]+]] +; DEBUG-NEXT: [[OV1:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1, !dbg [[DBG126]] +; DEBUG-NEXT: #dbg_value(i1 [[OV1]], [[META122:![0-9]+]], !DIExpression(), [[DBG126]]) +; DEBUG-NEXT: [[OV:%.*]] = xor i1 [[OV1]], true, !dbg [[DBG127:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i1 [[OV]], [[META123:![0-9]+]], !DIExpression(), [[DBG127]]) +; DEBUG-NEXT: ret i1 [[OV]], !dbg [[DBG128:![0-9]+]] ; %x = xor i32 %a, -1 %b = load i32, ptr %b.ptr, align 8 @@ -219,8 +350,17 @@ define i1 @uaddo_i64_increment(i64 %x, ptr %p) { ; CHECK-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[X:%.*]], i64 1) ; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0 ; CHECK-NEXT: [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1 -; CHECK-NEXT: store i64 [[MATH]], ptr [[P:%.*]] +; CHECK-NEXT: store i64 [[MATH]], ptr [[P:%.*]], align 8 ; CHECK-NEXT: ret i1 [[OV1]] +; +; DEBUG-LABEL: @uaddo_i64_increment( +; DEBUG-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[X:%.*]], i64 1), !dbg [[DBG133:![0-9]+]] +; DEBUG-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0, !dbg [[DBG133]] +; DEBUG-NEXT: [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !dbg [[DBG133]] +; DEBUG-NEXT: #dbg_value(i64 [[MATH]], [[META131:![0-9]+]], !DIExpression(), [[DBG133]]) +; DEBUG-NEXT: #dbg_value(i1 [[OV1]], [[META132:![0-9]+]], !DIExpression(), [[META134:![0-9]+]]) +; DEBUG-NEXT: store i64 [[MATH]], ptr [[P:%.*]], align 8, !dbg [[DBG135:![0-9]+]] +; DEBUG-NEXT: ret i1 [[OV1]], !dbg [[DBG136:![0-9]+]] ; %a = add i64 %x, 1 %ov = icmp eq i64 %a, 0 @@ -233,8 +373,17 @@ define i1 @uaddo_i8_increment_noncanonical_1(i8 %x, ptr %p) { ; CHECK-NEXT: [[TMP1:%.*]] = call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 1, i8 [[X:%.*]]) ; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i8, i1 } [[TMP1]], 0 ; CHECK-NEXT: [[OV1:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1 -; CHECK-NEXT: store i8 [[MATH]], ptr [[P:%.*]] +; CHECK-NEXT: store i8 [[MATH]], ptr [[P:%.*]], align 1 ; CHECK-NEXT: ret i1 [[OV1]] +; +; DEBUG-LABEL: @uaddo_i8_increment_noncanonical_1( +; DEBUG-NEXT: [[TMP1:%.*]] = call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 1, i8 [[X:%.*]]), !dbg [[DBG141:![0-9]+]] +; DEBUG-NEXT: [[MATH:%.*]] = extractvalue { i8, i1 } [[TMP1]], 0, !dbg [[DBG141]] +; DEBUG-NEXT: [[OV1:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1, !dbg [[DBG141]] +; DEBUG-NEXT: #dbg_value(i8 [[MATH]], [[META139:![0-9]+]], !DIExpression(), [[DBG141]]) +; DEBUG-NEXT: #dbg_value(i1 [[OV1]], [[META140:![0-9]+]], !DIExpression(), [[META142:![0-9]+]]) +; DEBUG-NEXT: store i8 [[MATH]], ptr [[P:%.*]], align 1, !dbg [[DBG143:![0-9]+]] +; DEBUG-NEXT: ret i1 [[OV1]], !dbg [[DBG144:![0-9]+]] ; %a = add i8 1, %x ; commute %ov = icmp eq i8 %a, 0 @@ -247,8 +396,17 @@ define i1 @uaddo_i32_increment_noncanonical_2(i32 %x, ptr %p) { ; CHECK-NEXT: [[TMP1:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[X:%.*]], i32 1) ; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0 ; CHECK-NEXT: [[OV1:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1 -; CHECK-NEXT: store i32 [[MATH]], ptr [[P:%.*]] +; CHECK-NEXT: store i32 [[MATH]], ptr [[P:%.*]], align 4 ; CHECK-NEXT: ret i1 [[OV1]] +; +; DEBUG-LABEL: @uaddo_i32_increment_noncanonical_2( +; DEBUG-NEXT: [[TMP1:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[X:%.*]], i32 1), !dbg [[DBG149:![0-9]+]] +; DEBUG-NEXT: [[MATH:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0, !dbg [[DBG149]] +; DEBUG-NEXT: [[OV1:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1, !dbg [[DBG149]] +; DEBUG-NEXT: #dbg_value(i32 [[MATH]], [[META147:![0-9]+]], !DIExpression(), [[DBG149]]) +; DEBUG-NEXT: #dbg_value(i1 [[OV1]], [[META148:![0-9]+]], !DIExpression(), [[META150:![0-9]+]]) +; DEBUG-NEXT: store i32 [[MATH]], ptr [[P:%.*]], align 4, !dbg [[DBG151:![0-9]+]] +; DEBUG-NEXT: ret i1 [[OV1]], !dbg [[DBG152:![0-9]+]] ; %a = add i32 %x, 1 %ov = icmp eq i32 0, %a ; commute @@ -261,8 +419,17 @@ define i1 @uaddo_i16_increment_noncanonical_3(i16 %x, ptr %p) { ; CHECK-NEXT: [[TMP1:%.*]] = call { i16, i1 } @llvm.uadd.with.overflow.i16(i16 1, i16 [[X:%.*]]) ; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i16, i1 } [[TMP1]], 0 ; CHECK-NEXT: [[OV1:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1 -; CHECK-NEXT: store i16 [[MATH]], ptr [[P:%.*]] +; CHECK-NEXT: store i16 [[MATH]], ptr [[P:%.*]], align 2 ; CHECK-NEXT: ret i1 [[OV1]] +; +; DEBUG-LABEL: @uaddo_i16_increment_noncanonical_3( +; DEBUG-NEXT: [[TMP1:%.*]] = call { i16, i1 } @llvm.uadd.with.overflow.i16(i16 1, i16 [[X:%.*]]), !dbg [[DBG158:![0-9]+]] +; DEBUG-NEXT: [[MATH:%.*]] = extractvalue { i16, i1 } [[TMP1]], 0, !dbg [[DBG158]] +; DEBUG-NEXT: [[OV1:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1, !dbg [[DBG158]] +; DEBUG-NEXT: #dbg_value(i16 [[MATH]], [[META155:![0-9]+]], !DIExpression(), [[DBG158]]) +; DEBUG-NEXT: #dbg_value(i1 [[OV1]], [[META157:![0-9]+]], !DIExpression(), [[META159:![0-9]+]]) +; DEBUG-NEXT: store i16 [[MATH]], ptr [[P:%.*]], align 2, !dbg [[DBG160:![0-9]+]] +; DEBUG-NEXT: ret i1 [[OV1]], !dbg [[DBG161:![0-9]+]] ; %a = add i16 1, %x ; commute %ov = icmp eq i16 0, %a ; commute @@ -277,8 +444,17 @@ define i1 @uaddo_i64_increment_alt(i64 %x, ptr %p) { ; CHECK-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[X:%.*]], i64 1) ; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0 ; CHECK-NEXT: [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1 -; CHECK-NEXT: store i64 [[MATH]], ptr [[P:%.*]] +; CHECK-NEXT: store i64 [[MATH]], ptr [[P:%.*]], align 8 ; CHECK-NEXT: ret i1 [[OV1]] +; +; DEBUG-LABEL: @uaddo_i64_increment_alt( +; DEBUG-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[X:%.*]], i64 1), !dbg [[DBG166:![0-9]+]] +; DEBUG-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0, !dbg [[DBG166]] +; DEBUG-NEXT: [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !dbg [[DBG166]] +; DEBUG-NEXT: #dbg_value(i64 [[MATH]], [[META164:![0-9]+]], !DIExpression(), [[DBG166]]) +; DEBUG-NEXT: store i64 [[MATH]], ptr [[P:%.*]], align 8, !dbg [[DBG167:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i1 [[OV1]], [[META165:![0-9]+]], !DIExpression(), [[META168:![0-9]+]]) +; DEBUG-NEXT: ret i1 [[OV1]], !dbg [[DBG169:![0-9]+]] ; %a = add i64 %x, 1 store i64 %a, ptr %p @@ -293,8 +469,17 @@ define i1 @uaddo_i64_increment_alt_dom(i64 %x, ptr %p) { ; CHECK-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[X:%.*]], i64 1) ; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0 ; CHECK-NEXT: [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1 -; CHECK-NEXT: store i64 [[MATH]], ptr [[P:%.*]] +; CHECK-NEXT: store i64 [[MATH]], ptr [[P:%.*]], align 8 ; CHECK-NEXT: ret i1 [[OV1]] +; +; DEBUG-LABEL: @uaddo_i64_increment_alt_dom( +; DEBUG-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[X:%.*]], i64 1), !dbg [[DBG174:![0-9]+]] +; DEBUG-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0, !dbg [[DBG174]] +; DEBUG-NEXT: [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !dbg [[DBG174]] +; DEBUG-NEXT: #dbg_value(i1 [[OV1]], [[META172:![0-9]+]], !DIExpression(), [[DBG174]]) +; DEBUG-NEXT: #dbg_value(i64 [[MATH]], [[META173:![0-9]+]], !DIExpression(), [[META175:![0-9]+]]) +; DEBUG-NEXT: store i64 [[MATH]], ptr [[P:%.*]], align 8, !dbg [[DBG176:![0-9]+]] +; DEBUG-NEXT: ret i1 [[OV1]], !dbg [[DBG177:![0-9]+]] ; %ov = icmp eq i64 %x, -1 %a = add i64 %x, 1 @@ -309,8 +494,17 @@ define i1 @uaddo_i64_decrement_alt(i64 %x, ptr %p) { ; CHECK-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[X:%.*]], i64 -1) ; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0 ; CHECK-NEXT: [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1 -; CHECK-NEXT: store i64 [[MATH]], ptr [[P:%.*]] +; CHECK-NEXT: store i64 [[MATH]], ptr [[P:%.*]], align 8 ; CHECK-NEXT: ret i1 [[OV1]] +; +; DEBUG-LABEL: @uaddo_i64_decrement_alt( +; DEBUG-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[X:%.*]], i64 -1), !dbg [[DBG182:![0-9]+]] +; DEBUG-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0, !dbg [[DBG182]] +; DEBUG-NEXT: [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !dbg [[DBG182]] +; DEBUG-NEXT: #dbg_value(i64 [[MATH]], [[META180:![0-9]+]], !DIExpression(), [[DBG182]]) +; DEBUG-NEXT: store i64 [[MATH]], ptr [[P:%.*]], align 8, !dbg [[DBG183:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i1 [[OV1]], [[META181:![0-9]+]], !DIExpression(), [[META184:![0-9]+]]) +; DEBUG-NEXT: ret i1 [[OV1]], !dbg [[DBG185:![0-9]+]] ; %a = add i64 %x, -1 store i64 %a, ptr %p @@ -325,8 +519,17 @@ define i1 @uaddo_i64_decrement_alt_dom(i64 %x, ptr %p) { ; CHECK-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[X:%.*]], i64 -1) ; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0 ; CHECK-NEXT: [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1 -; CHECK-NEXT: store i64 [[MATH]], ptr [[P:%.*]] +; CHECK-NEXT: store i64 [[MATH]], ptr [[P:%.*]], align 8 ; CHECK-NEXT: ret i1 [[OV1]] +; +; DEBUG-LABEL: @uaddo_i64_decrement_alt_dom( +; DEBUG-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[X:%.*]], i64 -1), !dbg [[DBG190:![0-9]+]] +; DEBUG-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0, !dbg [[DBG190]] +; DEBUG-NEXT: [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !dbg [[DBG190]] +; DEBUG-NEXT: #dbg_value(i1 [[OV1]], [[META188:![0-9]+]], !DIExpression(), [[DBG190]]) +; DEBUG-NEXT: #dbg_value(i64 [[MATH]], [[META189:![0-9]+]], !DIExpression(), [[META191:![0-9]+]]) +; DEBUG-NEXT: store i64 [[MATH]], ptr [[P:%.*]], align 8, !dbg [[DBG192:![0-9]+]] +; DEBUG-NEXT: ret i1 [[OV1]], !dbg [[DBG193:![0-9]+]] ; %ov = icmp ne i64 %x, 0 %a = add i64 %x, -1 @@ -340,8 +543,16 @@ define i1 @uaddo_i42_increment_illegal_type(i42 %x, ptr %p) { ; CHECK-LABEL: @uaddo_i42_increment_illegal_type( ; CHECK-NEXT: [[A:%.*]] = add i42 [[X:%.*]], 1 ; CHECK-NEXT: [[OV:%.*]] = icmp eq i42 [[A]], 0 -; CHECK-NEXT: store i42 [[A]], ptr [[P:%.*]] +; CHECK-NEXT: store i42 [[A]], ptr [[P:%.*]], align 8 ; CHECK-NEXT: ret i1 [[OV]] +; +; DEBUG-LABEL: @uaddo_i42_increment_illegal_type( +; DEBUG-NEXT: [[A:%.*]] = add i42 [[X:%.*]], 1, !dbg [[DBG198:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i42 [[A]], [[META196:![0-9]+]], !DIExpression(), [[DBG198]]) +; DEBUG-NEXT: [[OV:%.*]] = icmp eq i42 [[A]], 0, !dbg [[DBG199:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i1 [[OV]], [[META197:![0-9]+]], !DIExpression(), [[DBG199]]) +; DEBUG-NEXT: store i42 [[A]], ptr [[P:%.*]], align 8, !dbg [[DBG200:![0-9]+]] +; DEBUG-NEXT: ret i1 [[OV]], !dbg [[DBG201:![0-9]+]] ; %a = add i42 %x, 1 %ov = icmp eq i42 %a, 0 @@ -355,6 +566,14 @@ define i1 @usubo_ult_i64_overflow_used(i64 %x, i64 %y, ptr %p) { ; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0 ; CHECK-NEXT: [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1 ; CHECK-NEXT: ret i1 [[OV1]] +; +; DEBUG-LABEL: @usubo_ult_i64_overflow_used( +; DEBUG-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 [[X:%.*]], i64 [[Y:%.*]]), !dbg [[DBG206:![0-9]+]] +; DEBUG-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0, !dbg [[DBG206]] +; DEBUG-NEXT: [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !dbg [[DBG206]] +; DEBUG-NEXT: #dbg_value(i64 [[MATH]], [[META204:![0-9]+]], !DIExpression(), [[DBG206]]) +; DEBUG-NEXT: #dbg_value(i1 [[OV1]], [[META205:![0-9]+]], !DIExpression(), [[META207:![0-9]+]]) +; DEBUG-NEXT: ret i1 [[OV1]], !dbg [[DBG208:![0-9]+]] ; %s = sub i64 %x, %y %ov = icmp ult i64 %x, %y @@ -366,8 +585,17 @@ define i1 @usubo_ult_i64_math_overflow_used(i64 %x, i64 %y, ptr %p) { ; CHECK-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 [[X:%.*]], i64 [[Y:%.*]]) ; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0 ; CHECK-NEXT: [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1 -; CHECK-NEXT: store i64 [[MATH]], ptr [[P:%.*]] +; CHECK-NEXT: store i64 [[MATH]], ptr [[P:%.*]], align 8 ; CHECK-NEXT: ret i1 [[OV1]] +; +; DEBUG-LABEL: @usubo_ult_i64_math_overflow_used( +; DEBUG-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 [[X:%.*]], i64 [[Y:%.*]]), !dbg [[DBG213:![0-9]+]] +; DEBUG-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0, !dbg [[DBG213]] +; DEBUG-NEXT: [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !dbg [[DBG213]] +; DEBUG-NEXT: #dbg_value(i64 [[MATH]], [[META211:![0-9]+]], !DIExpression(), [[DBG213]]) +; DEBUG-NEXT: store i64 [[MATH]], ptr [[P:%.*]], align 8, !dbg [[DBG214:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i1 [[OV1]], [[META212:![0-9]+]], !DIExpression(), [[META215:![0-9]+]]) +; DEBUG-NEXT: ret i1 [[OV1]], !dbg [[DBG216:![0-9]+]] ; %s = sub i64 %x, %y store i64 %s, ptr %p @@ -382,8 +610,17 @@ define i1 @usubo_ugt_i32(i32 %x, i32 %y, ptr %p) { ; CHECK-NEXT: [[TMP1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[X:%.*]], i32 [[Y:%.*]]) ; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0 ; CHECK-NEXT: [[OV1:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1 -; CHECK-NEXT: store i32 [[MATH]], ptr [[P:%.*]] +; CHECK-NEXT: store i32 [[MATH]], ptr [[P:%.*]], align 4 ; CHECK-NEXT: ret i1 [[OV1]] +; +; DEBUG-LABEL: @usubo_ugt_i32( +; DEBUG-NEXT: [[TMP1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[X:%.*]], i32 [[Y:%.*]]), !dbg [[DBG221:![0-9]+]] +; DEBUG-NEXT: [[MATH:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0, !dbg [[DBG221]] +; DEBUG-NEXT: [[OV1:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1, !dbg [[DBG221]] +; DEBUG-NEXT: #dbg_value(i1 [[OV1]], [[META219:![0-9]+]], !DIExpression(), [[DBG221]]) +; DEBUG-NEXT: #dbg_value(i32 [[MATH]], [[META220:![0-9]+]], !DIExpression(), [[META222:![0-9]+]]) +; DEBUG-NEXT: store i32 [[MATH]], ptr [[P:%.*]], align 4, !dbg [[DBG223:![0-9]+]] +; DEBUG-NEXT: ret i1 [[OV1]], !dbg [[DBG224:![0-9]+]] ; %ov = icmp ugt i32 %y, %x %s = sub i32 %x, %y @@ -398,8 +635,17 @@ define i1 @usubo_ugt_constant_op0_i8(i8 %x, ptr %p) { ; CHECK-NEXT: [[TMP1:%.*]] = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 42, i8 [[X:%.*]]) ; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i8, i1 } [[TMP1]], 0 ; CHECK-NEXT: [[OV1:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1 -; CHECK-NEXT: store i8 [[MATH]], ptr [[P:%.*]] +; CHECK-NEXT: store i8 [[MATH]], ptr [[P:%.*]], align 1 ; CHECK-NEXT: ret i1 [[OV1]] +; +; DEBUG-LABEL: @usubo_ugt_constant_op0_i8( +; DEBUG-NEXT: [[TMP1:%.*]] = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 42, i8 [[X:%.*]]), !dbg [[DBG229:![0-9]+]] +; DEBUG-NEXT: [[MATH:%.*]] = extractvalue { i8, i1 } [[TMP1]], 0, !dbg [[DBG229]] +; DEBUG-NEXT: [[OV1:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1, !dbg [[DBG229]] +; DEBUG-NEXT: #dbg_value(i8 [[MATH]], [[META227:![0-9]+]], !DIExpression(), [[DBG229]]) +; DEBUG-NEXT: #dbg_value(i1 [[OV1]], [[META228:![0-9]+]], !DIExpression(), [[META230:![0-9]+]]) +; DEBUG-NEXT: store i8 [[MATH]], ptr [[P:%.*]], align 1, !dbg [[DBG231:![0-9]+]] +; DEBUG-NEXT: ret i1 [[OV1]], !dbg [[DBG232:![0-9]+]] ; %s = sub i8 42, %x %ov = icmp ugt i8 %x, 42 @@ -414,8 +660,17 @@ define i1 @usubo_ult_constant_op0_i16(i16 %x, ptr %p) { ; CHECK-NEXT: [[TMP1:%.*]] = call { i16, i1 } @llvm.usub.with.overflow.i16(i16 43, i16 [[X:%.*]]) ; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i16, i1 } [[TMP1]], 0 ; CHECK-NEXT: [[OV1:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1 -; CHECK-NEXT: store i16 [[MATH]], ptr [[P:%.*]] +; CHECK-NEXT: store i16 [[MATH]], ptr [[P:%.*]], align 2 ; CHECK-NEXT: ret i1 [[OV1]] +; +; DEBUG-LABEL: @usubo_ult_constant_op0_i16( +; DEBUG-NEXT: [[TMP1:%.*]] = call { i16, i1 } @llvm.usub.with.overflow.i16(i16 43, i16 [[X:%.*]]), !dbg [[DBG237:![0-9]+]] +; DEBUG-NEXT: [[MATH:%.*]] = extractvalue { i16, i1 } [[TMP1]], 0, !dbg [[DBG237]] +; DEBUG-NEXT: [[OV1:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1, !dbg [[DBG237]] +; DEBUG-NEXT: #dbg_value(i16 [[MATH]], [[META235:![0-9]+]], !DIExpression(), [[DBG237]]) +; DEBUG-NEXT: #dbg_value(i1 [[OV1]], [[META236:![0-9]+]], !DIExpression(), [[META238:![0-9]+]]) +; DEBUG-NEXT: store i16 [[MATH]], ptr [[P:%.*]], align 2, !dbg [[DBG239:![0-9]+]] +; DEBUG-NEXT: ret i1 [[OV1]], !dbg [[DBG240:![0-9]+]] ; %s = sub i16 43, %x %ov = icmp ult i16 43, %x @@ -430,8 +685,17 @@ define i1 @usubo_ult_constant_op1_i16(i16 %x, ptr %p) { ; CHECK-NEXT: [[TMP1:%.*]] = call { i16, i1 } @llvm.usub.with.overflow.i16(i16 [[X:%.*]], i16 44) ; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i16, i1 } [[TMP1]], 0 ; CHECK-NEXT: [[OV1:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1 -; CHECK-NEXT: store i16 [[MATH]], ptr [[P:%.*]] +; CHECK-NEXT: store i16 [[MATH]], ptr [[P:%.*]], align 2 ; CHECK-NEXT: ret i1 [[OV1]] +; +; DEBUG-LABEL: @usubo_ult_constant_op1_i16( +; DEBUG-NEXT: [[TMP1:%.*]] = call { i16, i1 } @llvm.usub.with.overflow.i16(i16 [[X:%.*]], i16 44), !dbg [[DBG245:![0-9]+]] +; DEBUG-NEXT: [[MATH:%.*]] = extractvalue { i16, i1 } [[TMP1]], 0, !dbg [[DBG245]] +; DEBUG-NEXT: [[OV1:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1, !dbg [[DBG245]] +; DEBUG-NEXT: #dbg_value(i16 [[MATH]], [[META243:![0-9]+]], !DIExpression(), [[DBG245]]) +; DEBUG-NEXT: #dbg_value(i1 [[OV1]], [[META244:![0-9]+]], !DIExpression(), [[META246:![0-9]+]]) +; DEBUG-NEXT: store i16 [[MATH]], ptr [[P:%.*]], align 2, !dbg [[DBG247:![0-9]+]] +; DEBUG-NEXT: ret i1 [[OV1]], !dbg [[DBG248:![0-9]+]] ; %s = add i16 %x, -44 %ov = icmp ult i16 %x, 44 @@ -444,8 +708,17 @@ define i1 @usubo_ugt_constant_op1_i8(i8 %x, ptr %p) { ; CHECK-NEXT: [[TMP1:%.*]] = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[X:%.*]], i8 45) ; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i8, i1 } [[TMP1]], 0 ; CHECK-NEXT: [[OV1:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1 -; CHECK-NEXT: store i8 [[MATH]], ptr [[P:%.*]] +; CHECK-NEXT: store i8 [[MATH]], ptr [[P:%.*]], align 1 ; CHECK-NEXT: ret i1 [[OV1]] +; +; DEBUG-LABEL: @usubo_ugt_constant_op1_i8( +; DEBUG-NEXT: [[TMP1:%.*]] = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[X:%.*]], i8 45), !dbg [[DBG253:![0-9]+]] +; DEBUG-NEXT: [[MATH:%.*]] = extractvalue { i8, i1 } [[TMP1]], 0, !dbg [[DBG253]] +; DEBUG-NEXT: [[OV1:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1, !dbg [[DBG253]] +; DEBUG-NEXT: #dbg_value(i1 [[OV1]], [[META251:![0-9]+]], !DIExpression(), [[DBG253]]) +; DEBUG-NEXT: #dbg_value(i8 [[MATH]], [[META252:![0-9]+]], !DIExpression(), [[META254:![0-9]+]]) +; DEBUG-NEXT: store i8 [[MATH]], ptr [[P:%.*]], align 1, !dbg [[DBG255:![0-9]+]] +; DEBUG-NEXT: ret i1 [[OV1]], !dbg [[DBG256:![0-9]+]] ; %ov = icmp ugt i8 45, %x %s = add i8 %x, -45 @@ -460,8 +733,17 @@ define i1 @usubo_eq_constant1_op1_i32(i32 %x, ptr %p) { ; CHECK-NEXT: [[TMP1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[X:%.*]], i32 1) ; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0 ; CHECK-NEXT: [[OV1:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1 -; CHECK-NEXT: store i32 [[MATH]], ptr [[P:%.*]] +; CHECK-NEXT: store i32 [[MATH]], ptr [[P:%.*]], align 4 ; CHECK-NEXT: ret i1 [[OV1]] +; +; DEBUG-LABEL: @usubo_eq_constant1_op1_i32( +; DEBUG-NEXT: [[TMP1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[X:%.*]], i32 1), !dbg [[DBG261:![0-9]+]] +; DEBUG-NEXT: [[MATH:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0, !dbg [[DBG261]] +; DEBUG-NEXT: [[OV1:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1, !dbg [[DBG261]] +; DEBUG-NEXT: #dbg_value(i32 [[MATH]], [[META259:![0-9]+]], !DIExpression(), [[DBG261]]) +; DEBUG-NEXT: #dbg_value(i1 [[OV1]], [[META260:![0-9]+]], !DIExpression(), [[META262:![0-9]+]]) +; DEBUG-NEXT: store i32 [[MATH]], ptr [[P:%.*]], align 4, !dbg [[DBG263:![0-9]+]] +; DEBUG-NEXT: ret i1 [[OV1]], !dbg [[DBG264:![0-9]+]] ; %s = add i32 %x, -1 %ov = icmp eq i32 %x, 0 @@ -476,8 +758,17 @@ define i1 @usubo_ne_constant0_op1_i32(i32 %x, ptr %p) { ; CHECK-NEXT: [[TMP1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 0, i32 [[X:%.*]]) ; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0 ; CHECK-NEXT: [[OV1:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1 -; CHECK-NEXT: store i32 [[MATH]], ptr [[P:%.*]] +; CHECK-NEXT: store i32 [[MATH]], ptr [[P:%.*]], align 4 ; CHECK-NEXT: ret i1 [[OV1]] +; +; DEBUG-LABEL: @usubo_ne_constant0_op1_i32( +; DEBUG-NEXT: [[TMP1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 0, i32 [[X:%.*]]), !dbg [[DBG269:![0-9]+]] +; DEBUG-NEXT: [[MATH:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0, !dbg [[DBG269]] +; DEBUG-NEXT: [[OV1:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1, !dbg [[DBG269]] +; DEBUG-NEXT: #dbg_value(i32 [[MATH]], [[META267:![0-9]+]], !DIExpression(), [[DBG269]]) +; DEBUG-NEXT: #dbg_value(i1 [[OV1]], [[META268:![0-9]+]], !DIExpression(), [[META270:![0-9]+]]) +; DEBUG-NEXT: store i32 [[MATH]], ptr [[P:%.*]], align 4, !dbg [[DBG271:![0-9]+]] +; DEBUG-NEXT: ret i1 [[OV1]], !dbg [[DBG272:![0-9]+]] ; %s = sub i32 0, %x %ov = icmp ne i32 %x, 0 @@ -495,7 +786,7 @@ define i1 @usubo_ult_sub_dominates_i64(i64 %x, i64 %y, ptr %p, i1 %cond) { ; CHECK-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]] ; CHECK: t: ; CHECK-NEXT: [[S:%.*]] = sub i64 [[X:%.*]], [[Y:%.*]] -; CHECK-NEXT: store i64 [[S]], ptr [[P:%.*]] +; CHECK-NEXT: store i64 [[S]], ptr [[P:%.*]], align 8 ; CHECK-NEXT: br i1 [[COND]], label [[END:%.*]], label [[F]] ; CHECK: f: ; CHECK-NEXT: ret i1 [[COND]] @@ -503,6 +794,21 @@ define i1 @usubo_ult_sub_dominates_i64(i64 %x, i64 %y, ptr %p, i1 %cond) { ; CHECK-NEXT: [[OV:%.*]] = icmp ult i64 [[X]], [[Y]] ; CHECK-NEXT: ret i1 [[OV]] ; +; DEBUG-LABEL: @usubo_ult_sub_dominates_i64( +; DEBUG-NEXT: entry: +; DEBUG-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]], !dbg [[DBG277:![0-9]+]] +; DEBUG: t: +; DEBUG-NEXT: [[S:%.*]] = sub i64 [[X:%.*]], [[Y:%.*]], !dbg [[DBG278:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i64 [[S]], [[META275:![0-9]+]], !DIExpression(), [[DBG278]]) +; DEBUG-NEXT: store i64 [[S]], ptr [[P:%.*]], align 8, !dbg [[DBG279:![0-9]+]] +; DEBUG-NEXT: br i1 [[COND]], label [[END:%.*]], label [[F]], !dbg [[DBG280:![0-9]+]] +; DEBUG: f: +; DEBUG-NEXT: ret i1 [[COND]], !dbg [[DBG281:![0-9]+]] +; DEBUG: end: +; DEBUG-NEXT: [[OV:%.*]] = icmp ult i64 [[X]], [[Y]], !dbg [[DBG282:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i1 [[OV]], [[META276:![0-9]+]], !DIExpression(), [[DBG282]]) +; DEBUG-NEXT: ret i1 [[OV]], !dbg [[DBG283:![0-9]+]] +; entry: br i1 %cond, label %t, label %f @@ -533,9 +839,27 @@ define i1 @usubo_ult_cmp_dominates_i64(i64 %x, i64 %y, ptr %p, i1 %cond) { ; CHECK-NEXT: [[TMP0:%.*]] = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 [[X]], i64 [[Y]]) ; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP0]], 0 ; CHECK-NEXT: [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP0]], 1 -; CHECK-NEXT: store i64 [[MATH]], ptr [[P:%.*]] +; CHECK-NEXT: store i64 [[MATH]], ptr [[P:%.*]], align 8 ; CHECK-NEXT: ret i1 [[OV1]] ; +; DEBUG-LABEL: @usubo_ult_cmp_dominates_i64( +; DEBUG-NEXT: entry: +; DEBUG-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[F:%.*]], !dbg [[DBG288:![0-9]+]] +; DEBUG: t: +; DEBUG-NEXT: [[OV:%.*]] = icmp ult i64 [[X:%.*]], [[Y:%.*]], !dbg [[DBG289:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i1 [[OV]], [[META286:![0-9]+]], !DIExpression(), [[DBG289]]) +; DEBUG-NEXT: call void @call(i1 [[OV]]), !dbg [[DBG290:![0-9]+]] +; DEBUG-NEXT: br i1 [[OV]], label [[END:%.*]], label [[F]], !dbg [[DBG291:![0-9]+]] +; DEBUG: f: +; DEBUG-NEXT: ret i1 [[COND]], !dbg [[DBG292:![0-9]+]] +; DEBUG: end: +; DEBUG-NEXT: [[TMP0:%.*]] = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 [[X]], i64 [[Y]]), !dbg [[DBG289]] +; DEBUG-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP0]], 0, !dbg [[DBG289]] +; DEBUG-NEXT: [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP0]], 1, !dbg [[DBG289]] +; DEBUG-NEXT: #dbg_value(i64 [[MATH]], [[META287:![0-9]+]], !DIExpression(), [[META293:![0-9]+]]) +; DEBUG-NEXT: store i64 [[MATH]], ptr [[P:%.*]], align 8, !dbg [[DBG294:![0-9]+]] +; DEBUG-NEXT: ret i1 [[OV1]], !dbg [[DBG295:![0-9]+]] +; entry: br i1 %cond, label %t, label %f @@ -560,6 +884,13 @@ define void @bar() { ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 1, -1 ; CHECK-NEXT: [[FROMBOOL:%.*]] = zext i1 [[CMP]] to i8 ; CHECK-NEXT: unreachable +; +; DEBUG-LABEL: @bar( +; DEBUG-NEXT: [[CMP:%.*]] = icmp eq i64 1, -1, !dbg [[DBG300:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i1 [[CMP]], [[META298:![0-9]+]], !DIExpression(), [[DBG300]]) +; DEBUG-NEXT: [[FROMBOOL:%.*]] = zext i1 [[CMP]] to i8, !dbg [[DBG301:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i8 [[FROMBOOL]], [[META299:![0-9]+]], !DIExpression(), [[DBG301]]) +; DEBUG-NEXT: unreachable, !dbg [[DBG302:![0-9]+]] ; %cmp = icmp eq i64 1, -1 %frombool = zext i1 %cmp to i8 @@ -571,6 +902,13 @@ define void @foo() { ; CHECK-NEXT: [[SUB:%.*]] = add nsw i64 1, 1 ; CHECK-NEXT: [[CONV:%.*]] = trunc i64 [[SUB]] to i32 ; CHECK-NEXT: unreachable +; +; DEBUG-LABEL: @foo( +; DEBUG-NEXT: [[SUB:%.*]] = add nsw i64 1, 1, !dbg [[DBG307:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i64 [[SUB]], [[META305:![0-9]+]], !DIExpression(), [[DBG307]]) +; DEBUG-NEXT: [[CONV:%.*]] = trunc i64 [[SUB]] to i32, !dbg [[DBG308:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i32 [[CONV]], [[META306:![0-9]+]], !DIExpression(), [[DBG308]]) +; DEBUG-NEXT: unreachable, !dbg [[DBG309:![0-9]+]] ; %sub = add nsw i64 1, 1 %conv = trunc i64 %sub to i32 @@ -583,6 +921,11 @@ define i1 @bar2() { ; CHECK-LABEL: @bar2( ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 1, 0 ; CHECK-NEXT: ret i1 [[CMP]] +; +; DEBUG-LABEL: @bar2( +; DEBUG-NEXT: [[CMP:%.*]] = icmp eq i64 1, 0, !dbg [[DBG313:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i1 [[CMP]], [[META312:![0-9]+]], !DIExpression(), [[DBG313]]) +; DEBUG-NEXT: ret i1 [[CMP]], !dbg [[DBG314:![0-9]+]] ; %cmp = icmp eq i64 1, 0 ret i1 %cmp @@ -592,6 +935,11 @@ define i64 @foo2(ptr %p) { ; CHECK-LABEL: @foo2( ; CHECK-NEXT: [[SUB:%.*]] = add nsw i64 1, -1 ; CHECK-NEXT: ret i64 [[SUB]] +; +; DEBUG-LABEL: @foo2( +; DEBUG-NEXT: [[SUB:%.*]] = add nsw i64 1, -1, !dbg [[DBG318:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i64 [[SUB]], [[META317:![0-9]+]], !DIExpression(), [[DBG318]]) +; DEBUG-NEXT: ret i64 [[SUB]], !dbg [[DBG319:![0-9]+]] ; %sub = add nsw i64 1, -1 ret i64 %sub @@ -608,15 +956,35 @@ define void @PR41129(ptr %p64) { ; CHECK-NEXT: br i1 [[COND17]], label [[TRUE:%.*]], label [[FALSE:%.*]] ; CHECK: false: ; CHECK-NEXT: [[ANDVAL:%.*]] = and i64 [[KEY]], 7 -; CHECK-NEXT: store i64 [[ANDVAL]], ptr [[P64]] +; CHECK-NEXT: store i64 [[ANDVAL]], ptr [[P64]], align 8 ; CHECK-NEXT: br label [[EXIT:%.*]] ; CHECK: true: ; CHECK-NEXT: [[SVALUE:%.*]] = add i64 [[KEY]], -1 -; CHECK-NEXT: store i64 [[SVALUE]], ptr [[P64]] +; CHECK-NEXT: store i64 [[SVALUE]], ptr [[P64]], align 8 ; CHECK-NEXT: br label [[EXIT]] ; CHECK: exit: ; CHECK-NEXT: ret void ; +; DEBUG-LABEL: @PR41129( +; DEBUG-NEXT: entry: +; DEBUG-NEXT: [[KEY:%.*]] = load i64, ptr [[P64:%.*]], align 8, !dbg [[DBG326:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i64 [[KEY]], [[META322:![0-9]+]], !DIExpression(), [[DBG326]]) +; DEBUG-NEXT: [[COND17:%.*]] = icmp eq i64 [[KEY]], 0, !dbg [[DBG327:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i1 [[COND17]], [[META323:![0-9]+]], !DIExpression(), [[DBG327]]) +; DEBUG-NEXT: br i1 [[COND17]], label [[TRUE:%.*]], label [[FALSE:%.*]], !dbg [[DBG328:![0-9]+]] +; DEBUG: false: +; DEBUG-NEXT: [[ANDVAL:%.*]] = and i64 [[KEY]], 7, !dbg [[DBG329:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i64 [[ANDVAL]], [[META324:![0-9]+]], !DIExpression(), [[DBG329]]) +; DEBUG-NEXT: store i64 [[ANDVAL]], ptr [[P64]], align 8, !dbg [[DBG330:![0-9]+]] +; DEBUG-NEXT: br label [[EXIT:%.*]], !dbg [[DBG331:![0-9]+]] +; DEBUG: true: +; DEBUG-NEXT: [[SVALUE:%.*]] = add i64 [[KEY]], -1, !dbg [[DBG332:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i64 [[SVALUE]], [[META325:![0-9]+]], !DIExpression(), [[DBG332]]) +; DEBUG-NEXT: store i64 [[SVALUE]], ptr [[P64]], align 8, !dbg [[DBG333:![0-9]+]] +; DEBUG-NEXT: br label [[EXIT]], !dbg [[DBG334:![0-9]+]] +; DEBUG: exit: +; DEBUG-NEXT: ret void, !dbg [[DBG335:![0-9]+]] +; entry: %key = load i64, ptr %p64, align 8 %cond17 = icmp eq i64 %key, 0 @@ -636,6 +1004,125 @@ exit: ret void } +define i1 @usubo_uge_i64_overflow_used(i64 %x, i64 %y, ptr %p) { +; CHECK-LABEL: @usubo_uge_i64_overflow_used( +; CHECK-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 [[X:%.*]], i64 [[Y:%.*]]) +; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0 +; CHECK-NEXT: [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1 +; CHECK-NEXT: [[OV:%.*]] = xor i1 [[OV1]], true +; CHECK-NEXT: ret i1 [[OV]] +; +; DEBUG-LABEL: @usubo_uge_i64_overflow_used( +; DEBUG-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 [[X:%.*]], i64 [[Y:%.*]]), !dbg [[DBG340:![0-9]+]] +; DEBUG-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0, !dbg [[DBG340]] +; DEBUG-NEXT: [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !dbg [[DBG340]] +; DEBUG-NEXT: [[TMP2:%.*]] = xor i1 [[OV1]], true, !dbg [[DBG340]] +; DEBUG-NEXT: #dbg_value(i64 [[MATH]], [[META338:![0-9]+]], !DIExpression(), [[DBG340]]) +; DEBUG-NEXT: #dbg_value(i1 [[TMP2]], [[META339:![0-9]+]], !DIExpression(), [[META341:![0-9]+]]) +; DEBUG-NEXT: ret i1 [[TMP2]], !dbg [[DBG342:![0-9]+]] +; + %s = sub i64 %x, %y + %ov = icmp uge i64 %x, %y + ret i1 %ov +} + +define i1 @usubo_uge_i64_math_overflow_used(i64 %x, i64 %y, ptr %p) { +; CHECK-LABEL: @usubo_uge_i64_math_overflow_used( +; CHECK-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 [[X:%.*]], i64 [[Y:%.*]]) +; CHECK-NEXT: [[S:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0 +; CHECK-NEXT: [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1 +; CHECK-NEXT: [[OV:%.*]] = xor i1 [[OV1]], true +; CHECK-NEXT: store i64 [[S]], ptr [[P:%.*]], align 8 +; CHECK-NEXT: ret i1 [[OV]] +; +; DEBUG-LABEL: @usubo_uge_i64_math_overflow_used( +; DEBUG-NEXT: [[TMP1:%.*]] = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 [[X:%.*]], i64 [[Y:%.*]]), !dbg [[DBG347:![0-9]+]] +; DEBUG-NEXT: [[MATH:%.*]] = extractvalue { i64, i1 } [[TMP1]], 0, !dbg [[DBG347]] +; DEBUG-NEXT: [[OV1:%.*]] = extractvalue { i64, i1 } [[TMP1]], 1, !dbg [[DBG347]] +; DEBUG-NEXT: [[TMP2:%.*]] = xor i1 [[OV1]], true, !dbg [[DBG347]] +; DEBUG-NEXT: #dbg_value(i64 [[MATH]], [[META345:![0-9]+]], !DIExpression(), [[DBG347]]) +; DEBUG-NEXT: store i64 [[MATH]], ptr [[P:%.*]], align 8, !dbg [[DBG348:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i1 [[TMP2]], [[META346:![0-9]+]], !DIExpression(), [[META349:![0-9]+]]) +; DEBUG-NEXT: ret i1 [[TMP2]], !dbg [[DBG350:![0-9]+]] +; + %s = sub i64 %x, %y + store i64 %s, ptr %p + %ov = icmp uge i64 %x, %y + ret i1 %ov +} + +define i1 @usubo_ule_i32_overflow_used(i32 %x, i32 %y, ptr %p) { +; CHECK-LABEL: @usubo_ule_i32_overflow_used( +; CHECK-NEXT: [[TMP1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[Y:%.*]], i32 [[X:%.*]]) +; CHECK-NEXT: [[MATH:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0 +; CHECK-NEXT: [[OV1:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1 +; CHECK-NEXT: [[OV:%.*]] = xor i1 [[OV1]], true +; CHECK-NEXT: ret i1 [[OV]] +; +; DEBUG-LABEL: @usubo_ule_i32_overflow_used( +; DEBUG-NEXT: [[TMP1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[Y:%.*]], i32 [[X:%.*]]), !dbg [[DBG355:![0-9]+]] +; DEBUG-NEXT: [[MATH:%.*]] = extractvalue { i32, i1 } [[TMP1]], 0, !dbg [[DBG355]] +; DEBUG-NEXT: [[OV1:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1, !dbg [[DBG355]] +; DEBUG-NEXT: [[TMP2:%.*]] = xor i1 [[OV1]], true, !dbg [[DBG355]] +; DEBUG-NEXT: #dbg_value(i32 [[MATH]], [[META353:![0-9]+]], !DIExpression(), [[DBG355]]) +; DEBUG-NEXT: #dbg_value(i1 [[TMP2]], [[META354:![0-9]+]], !DIExpression(), [[META356:![0-9]+]]) +; DEBUG-NEXT: ret i1 [[TMP2]], !dbg [[DBG357:![0-9]+]] +; + %s = sub i32 %y, %x + %ov = icmp ule i32 %x, %y + ret i1 %ov +} + +define i1 @usubo_ne_zero_i16_overflow_used(i16 %x, ptr %p) { +; CHECK-LABEL: @usubo_ne_zero_i16_overflow_used( +; CHECK-NEXT: [[TMP1:%.*]] = call { i16, i1 } @llvm.usub.with.overflow.i16(i16 [[X:%.*]], i16 1) +; CHECK-NEXT: [[S:%.*]] = extractvalue { i16, i1 } [[TMP1]], 0 +; CHECK-NEXT: [[OV1:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1 +; CHECK-NEXT: [[OV:%.*]] = xor i1 [[OV1]], true +; CHECK-NEXT: store i16 [[S]], ptr [[P:%.*]], align 2 +; CHECK-NEXT: ret i1 [[OV]] +; +; DEBUG-LABEL: @usubo_ne_zero_i16_overflow_used( +; DEBUG-NEXT: [[TMP1:%.*]] = call { i16, i1 } @llvm.usub.with.overflow.i16(i16 [[X:%.*]], i16 1), !dbg [[DBG362:![0-9]+]] +; DEBUG-NEXT: [[MATH:%.*]] = extractvalue { i16, i1 } [[TMP1]], 0, !dbg [[DBG362]] +; DEBUG-NEXT: [[OV1:%.*]] = extractvalue { i16, i1 } [[TMP1]], 1, !dbg [[DBG362]] +; DEBUG-NEXT: [[TMP2:%.*]] = xor i1 [[OV1]], true, !dbg [[DBG362]] +; DEBUG-NEXT: #dbg_value(i16 [[MATH]], [[META360:![0-9]+]], !DIExpression(), [[DBG362]]) +; DEBUG-NEXT: store i16 [[MATH]], ptr [[P:%.*]], align 2, !dbg [[DBG363:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i1 [[TMP2]], [[META361:![0-9]+]], !DIExpression(), [[META364:![0-9]+]]) +; DEBUG-NEXT: ret i1 [[TMP2]], !dbg [[DBG365:![0-9]+]] +; + %s = sub i16 %x, 1 + store i16 %s, ptr %p + %ov = icmp ne i16 %x, 0 + ret i1 %ov +} + +define i1 @usubo_eq_zero_i8_overflow_used(i8 %x, ptr %p) { +; CHECK-LABEL: @usubo_eq_zero_i8_overflow_used( +; CHECK-NEXT: [[TMP1:%.*]] = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 0, i8 [[X:%.*]]) +; CHECK-NEXT: [[S:%.*]] = extractvalue { i8, i1 } [[TMP1]], 0 +; CHECK-NEXT: [[OV1:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1 +; CHECK-NEXT: [[OV:%.*]] = xor i1 [[OV1]], true +; CHECK-NEXT: store i8 [[S]], ptr [[P:%.*]], align 1 +; CHECK-NEXT: ret i1 [[OV]] +; +; DEBUG-LABEL: @usubo_eq_zero_i8_overflow_used( +; DEBUG-NEXT: [[TMP1:%.*]] = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 0, i8 [[X:%.*]]), !dbg [[DBG370:![0-9]+]] +; DEBUG-NEXT: [[MATH:%.*]] = extractvalue { i8, i1 } [[TMP1]], 0, !dbg [[DBG370]] +; DEBUG-NEXT: [[OV1:%.*]] = extractvalue { i8, i1 } [[TMP1]], 1, !dbg [[DBG370]] +; DEBUG-NEXT: [[TMP2:%.*]] = xor i1 [[OV1]], true, !dbg [[DBG370]] +; DEBUG-NEXT: #dbg_value(i8 [[MATH]], [[META368:![0-9]+]], !DIExpression(), [[DBG370]]) +; DEBUG-NEXT: store i8 [[MATH]], ptr [[P:%.*]], align 1, !dbg [[DBG371:![0-9]+]] +; DEBUG-NEXT: #dbg_value(i1 [[TMP2]], [[META369:![0-9]+]], !DIExpression(), [[META372:![0-9]+]]) +; DEBUG-NEXT: ret i1 [[TMP2]], !dbg [[DBG373:![0-9]+]] +; + %s = sub i8 0, %x + store i8 %s, ptr %p + %ov = icmp eq i8 %x, 0 + ret i1 %ov +} + ; Check that every instruction inserted by -passes='require,function(codegenprepare)' has a debug location. ; DEBUG: CheckModuleDebugify: PASS