68 changes: 50 additions & 18 deletions llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2035,24 +2035,35 @@ Instruction *InstCombinerImpl::foldICmpMulConstant(ICmpInst &Cmp,
return new ICmpInst(Pred, X, ConstantInt::getNullValue(MulTy));
}

if (MulC->isZero() || (!Mul->hasNoSignedWrap() && !Mul->hasNoUnsignedWrap()))
if (MulC->isZero())
return nullptr;

// If the multiply does not wrap, try to divide the compare constant by the
// multiplication factor.
// If the multiply does not wrap or the constant is odd, try to divide the
// compare constant by the multiplication factor.
if (Cmp.isEquality()) {
// (mul nsw X, MulC) == C --> X == C /s MulC
// (mul nsw X, MulC) eq/ne C --> X eq/ne C /s MulC
if (Mul->hasNoSignedWrap() && C.srem(*MulC).isZero()) {
Constant *NewC = ConstantInt::get(MulTy, C.sdiv(*MulC));
return new ICmpInst(Pred, X, NewC);
}
// (mul nuw X, MulC) == C --> X == C /u MulC
if (Mul->hasNoUnsignedWrap() && C.urem(*MulC).isZero()) {
Constant *NewC = ConstantInt::get(MulTy, C.udiv(*MulC));
return new ICmpInst(Pred, X, NewC);

// C % MulC == 0 is weaker than we could use if MulC is odd because it
// correct to transform if MulC * N == C including overflow. I.e with i8
// (icmp eq (mul X, 5), 101) -> (icmp eq X, 225) but since 101 % 5 != 0, we
// miss that case.
if (C.urem(*MulC).isZero()) {
// (mul nuw X, MulC) eq/ne C --> X eq/ne C /u MulC
// (mul X, OddC) eq/ne N * C --> X eq/ne N
if ((*MulC & 1).isOne() || Mul->hasNoUnsignedWrap()) {
Constant *NewC = ConstantInt::get(MulTy, C.udiv(*MulC));
return new ICmpInst(Pred, X, NewC);
}
}
}

if (!Mul->hasNoSignedWrap() && !Mul->hasNoUnsignedWrap())
return nullptr;

// With a matching no-overflow guarantee, fold the constants:
// (X * MulC) < C --> X < (C / MulC)
// (X * MulC) > C --> X > (C / MulC)
Expand Down Expand Up @@ -4393,16 +4404,37 @@ Instruction *InstCombinerImpl::foldICmpBinOp(ICmpInst &I,
}

{
// Try to remove shared constant multiplier from equality comparison:
// X * C == Y * C (with no overflowing/aliasing) --> X == Y
Value *X, *Y;
const APInt *C;
if (match(Op0, m_Mul(m_Value(X), m_APInt(C))) && *C != 0 &&
match(Op1, m_Mul(m_Value(Y), m_SpecificInt(*C))) && I.isEquality())
if (!C->countTrailingZeros() ||
(BO0 && BO1 && BO0->hasNoSignedWrap() && BO1->hasNoSignedWrap()) ||
(BO0 && BO1 && BO0->hasNoUnsignedWrap() && BO1->hasNoUnsignedWrap()))
return new ICmpInst(Pred, X, Y);
// Try to remove shared multiplier from comparison:
// X * Z u{lt/le/gt/ge}/eq/ne Y * Z
Value *X, *Y, *Z;
if (Pred == ICmpInst::getUnsignedPredicate(Pred) &&
((match(Op0, m_Mul(m_Value(X), m_Value(Z))) &&
match(Op1, m_c_Mul(m_Specific(Z), m_Value(Y)))) ||
(match(Op0, m_Mul(m_Value(Z), m_Value(X))) &&
match(Op1, m_c_Mul(m_Specific(Z), m_Value(Y)))))) {
bool NonZero;
if (ICmpInst::isEquality(Pred)) {
KnownBits ZKnown = computeKnownBits(Z, 0, &I);
// if Z % 2 != 0
// X * Z eq/ne Y * Z -> X eq/ne Y
if (ZKnown.countMaxTrailingZeros() == 0)
return new ICmpInst(Pred, X, Y);
NonZero = !ZKnown.One.isZero() ||
isKnownNonZero(Z, Q.DL, /*Depth=*/0, Q.AC, Q.CxtI, Q.DT);
// if Z != 0 and nsw(X * Z) and nsw(Y * Z)
// X * Z eq/ne Y * Z -> X eq/ne Y
if (NonZero && BO0 && BO1 && BO0->hasNoSignedWrap() &&
BO1->hasNoSignedWrap())
return new ICmpInst(Pred, X, Y);
} else
NonZero = isKnownNonZero(Z, Q.DL, /*Depth=*/0, Q.AC, Q.CxtI, Q.DT);

// If Z != 0 and nuw(X * Z) and nuw(Y * Z)
// X * Z u{lt/le/gt/ge}/eq/ne Y * Z -> X u{lt/le/gt/ge}/eq/ne Y
if (NonZero && BO0 && BO1 && BO0->hasNoUnsignedWrap() &&
BO1->hasNoUnsignedWrap())
return new ICmpInst(Pred, X, Y);
}
}

BinaryOperator *SRem = nullptr;
Expand Down
22 changes: 14 additions & 8 deletions llvm/test/CodeGen/X86/GlobalISel/select-blsi.mir
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,13 @@ body: |
liveins: $edi
; CHECK-LABEL: name: test_blsi32rr
; CHECK: [[COPY:%[0-9]+]]:gr32 = COPY $edi
; CHECK: [[BLSI32rr:%[0-9]+]]:gr32 = BLSI32rr [[COPY]], implicit-def $eflags
; CHECK: $edi = COPY [[BLSI32rr]]
; CHECK: liveins: $edi
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:gr32 = COPY $edi
; CHECK-NEXT: [[MOV32r0_:%[0-9]+]]:gr32 = MOV32r0 implicit-def $eflags
; CHECK-NEXT: [[SUB32rr:%[0-9]+]]:gr32 = SUB32rr [[MOV32r0_]], [[COPY]], implicit-def $eflags
; CHECK-NEXT: [[AND32rr:%[0-9]+]]:gr32 = AND32rr [[SUB32rr]], [[COPY]], implicit-def $eflags
; CHECK-NEXT: $edi = COPY [[AND32rr]]
%0(s32) = COPY $edi
%1(s32) = G_CONSTANT i32 0
%2(s32) = G_SUB %1, %0
Expand All @@ -50,11 +54,13 @@ body: |
liveins: $edi
; CHECK-LABEL: name: test_blsi32rr_nomatch
; CHECK: [[COPY:%[0-9]+]]:gr32 = COPY $edi
; CHECK: [[MOV32r0_:%[0-9]+]]:gr32 = MOV32r0 implicit-def $eflags
; CHECK: [[SUB32ri:%[0-9]+]]:gr32 = SUB32ri8 [[MOV32r0_]], 0, implicit-def $eflags
; CHECK: [[AND32rr:%[0-9]+]]:gr32 = AND32rr [[SUB32ri]], [[COPY]], implicit-def $eflags
; CHECK: $edi = COPY [[AND32rr]]
; CHECK: liveins: $edi
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:gr32 = COPY $edi
; CHECK-NEXT: [[MOV32r0_:%[0-9]+]]:gr32 = MOV32r0 implicit-def $eflags
; CHECK-NEXT: [[SUB32ri8_:%[0-9]+]]:gr32 = SUB32ri8 [[MOV32r0_]], 0, implicit-def $eflags
; CHECK-NEXT: [[AND32rr:%[0-9]+]]:gr32 = AND32rr [[SUB32ri8_]], [[COPY]], implicit-def $eflags
; CHECK-NEXT: $edi = COPY [[AND32rr]]
%0(s32) = COPY $edi
%1(s32) = G_CONSTANT i32 0
%2(s32) = G_SUB %1, %1
Expand Down
21 changes: 13 additions & 8 deletions llvm/test/CodeGen/X86/GlobalISel/select-blsr.mir
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,12 @@ body: |
liveins: $edi
; CHECK-LABEL: name: test_blsr32rr
; CHECK: [[COPY:%[0-9]+]]:gr32 = COPY $edi
; CHECK: [[BLSR32rr:%[0-9]+]]:gr32 = BLSR32rr [[COPY]], implicit-def $eflags
; CHECK: $edi = COPY [[BLSR32rr]]
; CHECK: liveins: $edi
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:gr32 = COPY $edi
; CHECK-NEXT: [[DEC32r:%[0-9]+]]:gr32 = DEC32r [[COPY]], implicit-def $eflags
; CHECK-NEXT: [[AND32rr:%[0-9]+]]:gr32 = AND32rr [[DEC32r]], [[COPY]], implicit-def $eflags
; CHECK-NEXT: $edi = COPY [[AND32rr]]
%0(s32) = COPY $edi
%1(s32) = G_CONSTANT i32 -1
%2(s32) = G_ADD %0, %1
Expand All @@ -47,11 +50,13 @@ body: |
liveins: $edi
; CHECK-LABEL: name: test_blsr32rr_nomatch
; CHECK: [[COPY:%[0-9]+]]:gr32 = COPY $edi
; CHECK: [[MOV32ri:%[0-9]+]]:gr32 = MOV32ri -1
; CHECK: [[DEC32r:%[0-9]+]]:gr32 = DEC32r [[MOV32ri]], implicit-def $eflags
; CHECK: [[AND32rr:%[0-9]+]]:gr32 = AND32rr [[DEC32r]], [[COPY]], implicit-def $eflags
; CHECK: $edi = COPY [[AND32rr]]
; CHECK: liveins: $edi
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[COPY:%[0-9]+]]:gr32 = COPY $edi
; CHECK-NEXT: [[MOV32ri:%[0-9]+]]:gr32 = MOV32ri -1
; CHECK-NEXT: [[DEC32r:%[0-9]+]]:gr32 = DEC32r [[MOV32ri]], implicit-def $eflags
; CHECK-NEXT: [[AND32rr:%[0-9]+]]:gr32 = AND32rr [[DEC32r]], [[COPY]], implicit-def $eflags
; CHECK-NEXT: $edi = COPY [[AND32rr]]
%0(s32) = COPY $edi
%1(s32) = G_CONSTANT i32 -1
%2(s32) = G_ADD %1, %1
Expand Down
36 changes: 12 additions & 24 deletions llvm/test/CodeGen/X86/add.ll
Original file line number Diff line number Diff line change
Expand Up @@ -575,19 +575,15 @@ define void @add_i32_128_flag(i32 %x) {
; X64-LINUX-LABEL: add_i32_128_flag:
; X64-LINUX: # %bb.0: # %entry
; X64-LINUX-NEXT: subl $-128, %edi
; X64-LINUX-NEXT: je .LBB19_1
; X64-LINUX-NEXT: # %bb.2: # %if.then
; X64-LINUX-NEXT: jmp bar_i32 # TAILCALL
; X64-LINUX-NEXT: .LBB19_1: # %if.end
; X64-LINUX-NEXT: jne bar_i32 # TAILCALL
; X64-LINUX-NEXT: # %bb.1: # %if.end
; X64-LINUX-NEXT: retq
;
; X64-WIN32-LABEL: add_i32_128_flag:
; X64-WIN32: # %bb.0: # %entry
; X64-WIN32-NEXT: subl $-128, %ecx
; X64-WIN32-NEXT: je .LBB19_1
; X64-WIN32-NEXT: # %bb.2: # %if.then
; X64-WIN32-NEXT: jmp bar_i32 # TAILCALL
; X64-WIN32-NEXT: .LBB19_1: # %if.end
; X64-WIN32-NEXT: jne bar_i32 # TAILCALL
; X64-WIN32-NEXT: # %bb.1: # %if.end
; X64-WIN32-NEXT: retq
entry:
%add = add i32 %x, 128
Expand Down Expand Up @@ -627,19 +623,15 @@ define void @add_i64_128_flag(i64 %x) {
; X64-LINUX-LABEL: add_i64_128_flag:
; X64-LINUX: # %bb.0: # %entry
; X64-LINUX-NEXT: subq $-128, %rdi
; X64-LINUX-NEXT: je .LBB20_1
; X64-LINUX-NEXT: # %bb.2: # %if.then
; X64-LINUX-NEXT: jmp bar_i64 # TAILCALL
; X64-LINUX-NEXT: .LBB20_1: # %if.end
; X64-LINUX-NEXT: jne bar_i64 # TAILCALL
; X64-LINUX-NEXT: # %bb.1: # %if.end
; X64-LINUX-NEXT: retq
;
; X64-WIN32-LABEL: add_i64_128_flag:
; X64-WIN32: # %bb.0: # %entry
; X64-WIN32-NEXT: subq $-128, %rcx
; X64-WIN32-NEXT: je .LBB20_1
; X64-WIN32-NEXT: # %bb.2: # %if.then
; X64-WIN32-NEXT: jmp bar_i64 # TAILCALL
; X64-WIN32-NEXT: .LBB20_1: # %if.end
; X64-WIN32-NEXT: jne bar_i64 # TAILCALL
; X64-WIN32-NEXT: # %bb.1: # %if.end
; X64-WIN32-NEXT: retq
entry:
%add = add i64 %x, 128
Expand Down Expand Up @@ -679,19 +671,15 @@ define void @add_i64_2147483648_flag(i64 %x) {
; X64-LINUX-LABEL: add_i64_2147483648_flag:
; X64-LINUX: # %bb.0: # %entry
; X64-LINUX-NEXT: subq $-2147483648, %rdi # imm = 0x80000000
; X64-LINUX-NEXT: je .LBB21_1
; X64-LINUX-NEXT: # %bb.2: # %if.then
; X64-LINUX-NEXT: jmp bar_i64 # TAILCALL
; X64-LINUX-NEXT: .LBB21_1: # %if.end
; X64-LINUX-NEXT: jne bar_i64 # TAILCALL
; X64-LINUX-NEXT: # %bb.1: # %if.end
; X64-LINUX-NEXT: retq
;
; X64-WIN32-LABEL: add_i64_2147483648_flag:
; X64-WIN32: # %bb.0: # %entry
; X64-WIN32-NEXT: subq $-2147483648, %rcx # imm = 0x80000000
; X64-WIN32-NEXT: je .LBB21_1
; X64-WIN32-NEXT: # %bb.2: # %if.then
; X64-WIN32-NEXT: jmp bar_i64 # TAILCALL
; X64-WIN32-NEXT: .LBB21_1: # %if.end
; X64-WIN32-NEXT: jne bar_i64 # TAILCALL
; X64-WIN32-NEXT: # %bb.1: # %if.end
; X64-WIN32-NEXT: retq
entry:
%add = add i64 %x, 2147483648
Expand Down
6 changes: 2 additions & 4 deletions llvm/test/CodeGen/X86/atom-pad-short-functions.ll
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,8 @@ define void @test_call_others(i32 %x) nounwind {
; CHECK-LABEL: test_call_others:
; CHECK: # %bb.0:
; CHECK-NEXT: cmpl $0, {{[0-9]+}}(%esp)
; CHECK-NEXT: je .LBB6_1
; CHECK-NEXT: # %bb.2: # %true.case
; CHECK-NEXT: jmp external_function@PLT # TAILCALL
; CHECK-NEXT: .LBB6_1: # %if.end
; CHECK-NEXT: jne external_function@PLT # TAILCALL
; CHECK-NEXT: # %bb.1: # %if.end
; CHECK-NEXT: nop
; CHECK-NEXT: nop
; CHECK-NEXT: nop
Expand Down
6 changes: 2 additions & 4 deletions llvm/test/CodeGen/X86/avx512-i1test.ll
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,8 @@ define i64 @func2(i1 zeroext %i, i32 %j) {
; CHECK-LABEL: func2:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: testl %esi, %esi
; CHECK-NEXT: je .LBB1_1
; CHECK-NEXT: # %bb.2: # %if.then
; CHECK-NEXT: jmp bar # TAILCALL
; CHECK-NEXT: .LBB1_1: # %if.end
; CHECK-NEXT: jne bar # TAILCALL
; CHECK-NEXT: # %bb.1: # %if.end
; CHECK-NEXT: movzbl %dil, %eax
; CHECK-NEXT: orq $-2, %rax
; CHECK-NEXT: retq
Expand Down
65 changes: 24 additions & 41 deletions llvm/test/CodeGen/X86/bmi-out-of-order.ll
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@ define i32 @blsmsk_used2(i32 %a) nounwind {
; X86-LABEL: blsmsk_used2:
; X86: # %bb.0: # %entry
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
; X86-NEXT: blsmskl %eax, %ecx
; X86-NEXT: decl %eax
; X86-NEXT: leal -1(%eax), %ecx
; X86-NEXT: xorl %ecx, %eax
; X86-NEXT: imull %ecx, %eax
; X86-NEXT: retl
;
; X64-LABEL: blsmsk_used2:
; X64: # %bb.0: # %entry
; X64-NEXT: # kill: def $edi killed $edi def $rdi
; X64-NEXT: blsmskl %edi, %ecx
; X64-NEXT: leal -1(%rdi), %eax
; X64-NEXT: imull %ecx, %eax
; X64-NEXT: xorl %eax, %edi
; X64-NEXT: imull %edi, %eax
; X64-NEXT: retq
entry:
%sub = add i32 %a, -1
Expand Down Expand Up @@ -44,8 +44,7 @@ define i64 @blsmask_through1(i64 %a, i64 %b) nounwind {
;
; X64-LABEL: blsmask_through1:
; X64: # %bb.0: # %entry
; X64-NEXT: xorq %rsi, %rdi
; X64-NEXT: leaq -1(%rsi), %rax
; X64-NEXT: blsmskq %rsi, %rax
; X64-NEXT: xorq %rdi, %rax
; X64-NEXT: retq
entry:
Expand All @@ -58,20 +57,16 @@ entry:
define i32 @blsmask_through2(i32 %a, i32 %b, i32 %c) nounwind {
; X86-LABEL: blsmask_through2:
; X86: # %bb.0: # %entry
; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
; X86-NEXT: leal -1(%ecx), %eax
; X86-NEXT: blsmskl {{[0-9]+}}(%esp), %eax
; X86-NEXT: xorl {{[0-9]+}}(%esp), %eax
; X86-NEXT: xorl {{[0-9]+}}(%esp), %eax
; X86-NEXT: xorl %ecx, %eax
; X86-NEXT: retl
;
; X64-LABEL: blsmask_through2:
; X64: # %bb.0: # %entry
; X64-NEXT: # kill: def $esi killed $esi def $rsi
; X64-NEXT: leal -1(%rsi), %eax
; X64-NEXT: blsmskl %esi, %eax
; X64-NEXT: xorl %edx, %edi
; X64-NEXT: xorl %edi, %eax
; X64-NEXT: xorl %esi, %eax
; X64-NEXT: retq
entry:
%sub = add nsw i32 %b, -1
Expand Down Expand Up @@ -201,15 +196,17 @@ define i32 @blsi_used2(i32 %a) nounwind {
; X86-LABEL: blsi_used2:
; X86: # %bb.0: # %entry
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
; X86-NEXT: blsil %eax, %ecx
; X86-NEXT: negl %eax
; X86-NEXT: movl %eax, %ecx
; X86-NEXT: negl %ecx
; X86-NEXT: andl %ecx, %eax
; X86-NEXT: imull %ecx, %eax
; X86-NEXT: retl
;
; X64-LABEL: blsi_used2:
; X64: # %bb.0: # %entry
; X64-NEXT: blsil %edi, %eax
; X64-NEXT: negl %edi
; X64-NEXT: movl %edi, %eax
; X64-NEXT: negl %eax
; X64-NEXT: andl %eax, %edi
; X64-NEXT: imull %edi, %eax
; X64-NEXT: retq
entry:
Expand Down Expand Up @@ -238,9 +235,7 @@ define i64 @blsi_through1(i64 %a, i64 %b) nounwind {
;
; X64-LABEL: blsi_through1:
; X64: # %bb.0: # %entry
; X64-NEXT: movq %rsi, %rax
; X64-NEXT: andq %rsi, %rdi
; X64-NEXT: negq %rax
; X64-NEXT: blsiq %rsi, %rax
; X64-NEXT: andq %rdi, %rax
; X64-NEXT: retq
entry:
Expand All @@ -253,21 +248,16 @@ entry:
define i32 @blsi_through2(i32 %a, i32 %b, i32 %c) nounwind {
; X86-LABEL: blsi_through2:
; X86: # %bb.0: # %entry
; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
; X86-NEXT: movl %ecx, %eax
; X86-NEXT: negl %eax
; X86-NEXT: blsil {{[0-9]+}}(%esp), %eax
; X86-NEXT: andl {{[0-9]+}}(%esp), %eax
; X86-NEXT: andl {{[0-9]+}}(%esp), %eax
; X86-NEXT: andl %ecx, %eax
; X86-NEXT: retl
;
; X64-LABEL: blsi_through2:
; X64: # %bb.0: # %entry
; X64-NEXT: movl %esi, %eax
; X64-NEXT: negl %eax
; X64-NEXT: blsil %esi, %eax
; X64-NEXT: andl %edx, %edi
; X64-NEXT: andl %edi, %eax
; X64-NEXT: andl %esi, %eax
; X64-NEXT: retq
entry:
%sub = sub i32 0, %b
Expand Down Expand Up @@ -298,11 +288,9 @@ define i64 @blsi_through3(i64 %a, i64 %b, i64 %c) nounwind {
;
; X64-LABEL: blsi_through3:
; X64: # %bb.0: # %entry
; X64-NEXT: movq %rsi, %rax
; X64-NEXT: negq %rax
; X64-NEXT: blsiq %rsi, %rax
; X64-NEXT: andq %rdx, %rdi
; X64-NEXT: andq %rdi, %rax
; X64-NEXT: andq %rsi, %rax
; X64-NEXT: retq
entry:
%sub = sub i64 0, %b
Expand Down Expand Up @@ -394,17 +382,17 @@ define i32 @blsr_used2(i32 %a) nounwind {
; X86-LABEL: blsr_used2:
; X86: # %bb.0: # %entry
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
; X86-NEXT: blsrl %eax, %ecx
; X86-NEXT: decl %eax
; X86-NEXT: leal -1(%eax), %ecx
; X86-NEXT: andl %ecx, %eax
; X86-NEXT: imull %ecx, %eax
; X86-NEXT: retl
;
; X64-LABEL: blsr_used2:
; X64: # %bb.0: # %entry
; X64-NEXT: # kill: def $edi killed $edi def $rdi
; X64-NEXT: blsrl %edi, %ecx
; X64-NEXT: leal -1(%rdi), %eax
; X64-NEXT: imull %ecx, %eax
; X64-NEXT: andl %eax, %edi
; X64-NEXT: imull %edi, %eax
; X64-NEXT: retq
entry:
%sub = add i32 %a, -1
Expand Down Expand Up @@ -432,8 +420,7 @@ define i64 @blsr_through1(i64 %a, i64 %b) nounwind {
;
; X64-LABEL: blsr_through1:
; X64: # %bb.0: # %entry
; X64-NEXT: andq %rsi, %rdi
; X64-NEXT: leaq -1(%rsi), %rax
; X64-NEXT: blsrq %rsi, %rax
; X64-NEXT: andq %rdi, %rax
; X64-NEXT: retq
entry:
Expand All @@ -446,20 +433,16 @@ entry:
define i32 @blsr_through2(i32 %a, i32 %b, i32 %c) nounwind {
; X86-LABEL: blsr_through2:
; X86: # %bb.0: # %entry
; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
; X86-NEXT: leal -1(%ecx), %eax
; X86-NEXT: blsrl {{[0-9]+}}(%esp), %eax
; X86-NEXT: andl {{[0-9]+}}(%esp), %eax
; X86-NEXT: andl {{[0-9]+}}(%esp), %eax
; X86-NEXT: andl %ecx, %eax
; X86-NEXT: retl
;
; X64-LABEL: blsr_through2:
; X64: # %bb.0: # %entry
; X64-NEXT: # kill: def $esi killed $esi def $rsi
; X64-NEXT: leal -1(%rsi), %eax
; X64-NEXT: blsrl %esi, %eax
; X64-NEXT: andl %edx, %edi
; X64-NEXT: andl %edi, %eax
; X64-NEXT: andl %esi, %eax
; X64-NEXT: retq
entry:
%sub = add nsw i32 %b, -1
Expand Down
30 changes: 10 additions & 20 deletions llvm/test/CodeGen/X86/bmi.ll
Original file line number Diff line number Diff line change
Expand Up @@ -1223,20 +1223,16 @@ define void @pr40060(i32, i32) {
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
; X86-NEXT: bextrl %eax, {{[0-9]+}}(%esp), %eax
; X86-NEXT: testl %eax, %eax
; X86-NEXT: js .LBB52_1
; X86-NEXT: # %bb.2:
; X86-NEXT: jmp bar # TAILCALL
; X86-NEXT: .LBB52_1:
; X86-NEXT: jns bar # TAILCALL
; X86-NEXT: # %bb.1:
; X86-NEXT: retl
;
; X64-LABEL: pr40060:
; X64: # %bb.0:
; X64-NEXT: bextrl %esi, %edi, %eax
; X64-NEXT: testl %eax, %eax
; X64-NEXT: js .LBB52_1
; X64-NEXT: # %bb.2:
; X64-NEXT: jmp bar # TAILCALL
; X64-NEXT: .LBB52_1:
; X64-NEXT: jns bar # TAILCALL
; X64-NEXT: # %bb.1:
; X64-NEXT: retq
%3 = tail call i32 @llvm.x86.bmi.bextr.32(i32 %0, i32 %1)
%4 = icmp sgt i32 %3, -1
Expand Down Expand Up @@ -1444,19 +1440,15 @@ define void @pr42118_i32(i32 %x) {
; X86-LABEL: pr42118_i32:
; X86: # %bb.0:
; X86-NEXT: blsrl {{[0-9]+}}(%esp), %eax
; X86-NEXT: jne .LBB57_1
; X86-NEXT: # %bb.2:
; X86-NEXT: jmp bar # TAILCALL
; X86-NEXT: .LBB57_1:
; X86-NEXT: je bar # TAILCALL
; X86-NEXT: # %bb.1:
; X86-NEXT: retl
;
; X64-LABEL: pr42118_i32:
; X64: # %bb.0:
; X64-NEXT: blsrl %edi, %eax
; X64-NEXT: jne .LBB57_1
; X64-NEXT: # %bb.2:
; X64-NEXT: jmp bar # TAILCALL
; X64-NEXT: .LBB57_1:
; X64-NEXT: je bar # TAILCALL
; X64-NEXT: # %bb.1:
; X64-NEXT: retq
%tmp = sub i32 0, %x
%tmp1 = and i32 %tmp, %x
Expand Down Expand Up @@ -1498,10 +1490,8 @@ define void @pr42118_i64(i64 %x) {
; X64-LABEL: pr42118_i64:
; X64: # %bb.0:
; X64-NEXT: blsrq %rdi, %rax
; X64-NEXT: jne .LBB58_1
; X64-NEXT: # %bb.2:
; X64-NEXT: jmp bar # TAILCALL
; X64-NEXT: .LBB58_1:
; X64-NEXT: je bar # TAILCALL
; X64-NEXT: # %bb.1:
; X64-NEXT: retq
%tmp = sub i64 0, %x
%tmp1 = and i64 %tmp, %x
Expand Down
6 changes: 2 additions & 4 deletions llvm/test/CodeGen/X86/brcond.ll
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,8 @@ define i32 @test1(i32 %a, i32 %b) nounwind ssp {
; CHECK-NEXT: movzbl {{[0-9]+}}(%esp), %eax
; CHECK-NEXT: xorb {{[0-9]+}}(%esp), %al
; CHECK-NEXT: testb $64, %al
; CHECK-NEXT: je LBB0_1
; CHECK-NEXT: ## %bb.2: ## %bb1
; CHECK-NEXT: jmp _bar ## TAILCALL
; CHECK-NEXT: LBB0_1: ## %bb
; CHECK-NEXT: jne _bar ## TAILCALL
; CHECK-NEXT: ## %bb.1: ## %bb
; CHECK-NEXT: jmp _foo ## TAILCALL
entry:
%0 = and i32 %a, 16384
Expand Down
8 changes: 2 additions & 6 deletions llvm/test/CodeGen/X86/btq.ll
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,9 @@ define void @test1(i64 %foo) nounwind {
; CHECK-LABEL: test1:
; CHECK: # %bb.0:
; CHECK-NEXT: btq $32, %rdi
; CHECK-NEXT: jb .LBB0_2
; CHECK-NEXT: jb bar # TAILCALL
; CHECK-NEXT: # %bb.1: # %if.end
; CHECK-NEXT: retq
; CHECK-NEXT: .LBB0_2: # %if.then
; CHECK-NEXT: jmp bar # TAILCALL
%and = and i64 %foo, 4294967296
%tobool = icmp eq i64 %and, 0
br i1 %tobool, label %if.end, label %if.then
Expand All @@ -28,11 +26,9 @@ define void @test2(i64 %foo) nounwind {
; CHECK-LABEL: test2:
; CHECK: # %bb.0:
; CHECK-NEXT: testl %edi, %edi
; CHECK-NEXT: js .LBB1_2
; CHECK-NEXT: js bar # TAILCALL
; CHECK-NEXT: # %bb.1: # %if.end
; CHECK-NEXT: retq
; CHECK-NEXT: .LBB1_2: # %if.then
; CHECK-NEXT: jmp bar # TAILCALL
%and = and i64 %foo, 2147483648
%tobool = icmp eq i64 %and, 0
br i1 %tobool, label %if.end, label %if.then
Expand Down
35 changes: 14 additions & 21 deletions llvm/test/CodeGen/X86/clz.ll
Original file line number Diff line number Diff line change
Expand Up @@ -968,7 +968,12 @@ define i32 @ctlz_i32_fold_cmov(i32 %n) {

; Don't generate any xors when a 'ctlz' intrinsic is actually used to compute
; the most significant bit, which is what 'bsr' does natively.
; FIXME: We should probably select BSR instead of LZCNT in these circumstances.
; NOTE: We intentionally don't select `bsr` when `fast-lzcnt` is
; available. This is 1) because `bsr` has some drawbacks including a
; dependency on dst, 2) very poor performance on some of the
; `fast-lzcnt` processors, and 3) `lzcnt` runs at ALU latency/throughput
; so `lzcnt` + `xor` has better throughput than even the 1-uop
; (1c latency, 1c throughput) `bsr`.
define i32 @ctlz_bsr(i32 %n) {
; X86-LABEL: ctlz_bsr:
; X86: # %bb.0:
Expand All @@ -982,14 +987,12 @@ define i32 @ctlz_bsr(i32 %n) {
;
; X86-CLZ-LABEL: ctlz_bsr:
; X86-CLZ: # %bb.0:
; X86-CLZ-NEXT: lzcntl {{[0-9]+}}(%esp), %eax
; X86-CLZ-NEXT: xorl $31, %eax
; X86-CLZ-NEXT: bsrl {{[0-9]+}}(%esp), %eax
; X86-CLZ-NEXT: retl
;
; X64-CLZ-LABEL: ctlz_bsr:
; X64-CLZ: # %bb.0:
; X64-CLZ-NEXT: lzcntl %edi, %eax
; X64-CLZ-NEXT: xorl $31, %eax
; X64-CLZ-NEXT: bsrl %edi, %eax
; X64-CLZ-NEXT: retq
;
; X64-FASTLZCNT-LABEL: ctlz_bsr:
Expand Down Expand Up @@ -1441,8 +1444,7 @@ define i32 @PR47603_zext(i32 %a0, ptr %a1) {
; X86-CLZ-LABEL: PR47603_zext:
; X86-CLZ: # %bb.0:
; X86-CLZ-NEXT: movl {{[0-9]+}}(%esp), %eax
; X86-CLZ-NEXT: lzcntl {{[0-9]+}}(%esp), %ecx
; X86-CLZ-NEXT: xorl $31, %ecx
; X86-CLZ-NEXT: bsrl {{[0-9]+}}(%esp), %ecx
; X86-CLZ-NEXT: movsbl (%eax,%ecx), %eax
; X86-CLZ-NEXT: retl
;
Expand Down Expand Up @@ -1566,18 +1568,14 @@ define i8 @ctlz_xor7_i8_true(i8 %x) {
; X86-CLZ-LABEL: ctlz_xor7_i8_true:
; X86-CLZ: # %bb.0:
; X86-CLZ-NEXT: movzbl {{[0-9]+}}(%esp), %eax
; X86-CLZ-NEXT: lzcntl %eax, %eax
; X86-CLZ-NEXT: addl $-24, %eax
; X86-CLZ-NEXT: xorb $7, %al
; X86-CLZ-NEXT: bsrl %eax, %eax
; X86-CLZ-NEXT: # kill: def $al killed $al killed $eax
; X86-CLZ-NEXT: retl
;
; X64-CLZ-LABEL: ctlz_xor7_i8_true:
; X64-CLZ: # %bb.0:
; X64-CLZ-NEXT: movzbl %dil, %eax
; X64-CLZ-NEXT: lzcntl %eax, %eax
; X64-CLZ-NEXT: addl $-24, %eax
; X64-CLZ-NEXT: xorb $7, %al
; X64-CLZ-NEXT: bsrl %eax, %eax
; X64-CLZ-NEXT: # kill: def $al killed $al killed $eax
; X64-CLZ-NEXT: retq
;
Expand Down Expand Up @@ -1692,16 +1690,12 @@ define i16 @ctlz_xor15_i16_true(i16 %x) {
;
; X86-CLZ-LABEL: ctlz_xor15_i16_true:
; X86-CLZ: # %bb.0:
; X86-CLZ-NEXT: lzcntw {{[0-9]+}}(%esp), %ax
; X86-CLZ-NEXT: xorl $15, %eax
; X86-CLZ-NEXT: # kill: def $ax killed $ax killed $eax
; X86-CLZ-NEXT: bsrw {{[0-9]+}}(%esp), %ax
; X86-CLZ-NEXT: retl
;
; X64-CLZ-LABEL: ctlz_xor15_i16_true:
; X64-CLZ: # %bb.0:
; X64-CLZ-NEXT: lzcntw %di, %ax
; X64-CLZ-NEXT: xorl $15, %eax
; X64-CLZ-NEXT: # kill: def $ax killed $ax killed $eax
; X64-CLZ-NEXT: bsrw %di, %ax
; X64-CLZ-NEXT: retq
;
; X64-FASTLZCNT-LABEL: ctlz_xor15_i16_true:
Expand Down Expand Up @@ -1836,8 +1830,7 @@ define i64 @ctlz_xor63_i64_true(i64 %x) {
;
; X64-CLZ-LABEL: ctlz_xor63_i64_true:
; X64-CLZ: # %bb.0:
; X64-CLZ-NEXT: lzcntq %rdi, %rax
; X64-CLZ-NEXT: xorq $63, %rax
; X64-CLZ-NEXT: bsrq %rdi, %rax
; X64-CLZ-NEXT: retq
;
; X64-FASTLZCNT-LABEL: ctlz_xor63_i64_true:
Expand Down
48 changes: 16 additions & 32 deletions llvm/test/CodeGen/X86/cmp-merge.ll
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,19 @@ define void @eq_first(i32 %0, i32 %1) {
; X86: # %bb.0:
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
; X86-NEXT: cmpl %eax, {{[0-9]+}}(%esp)
; X86-NEXT: jge .LBB0_1
; X86-NEXT: # %bb.3:
; X86-NEXT: jmp on_less@PLT # TAILCALL
; X86-NEXT: .LBB0_1:
; X86-NEXT: jne .LBB0_2
; X86-NEXT: # %bb.4:
; X86-NEXT: jmp on_equal@PLT # TAILCALL
; X86-NEXT: .LBB0_2:
; X86-NEXT: jl on_less@PLT # TAILCALL
; X86-NEXT: # %bb.1:
; X86-NEXT: je on_equal@PLT # TAILCALL
; X86-NEXT: # %bb.2:
; X86-NEXT: jmp on_greater@PLT # TAILCALL
;
; X64-LABEL: eq_first:
; X64: # %bb.0:
; X64-NEXT: cmpl %esi, %edi
; X64-NEXT: jge .LBB0_1
; X64-NEXT: # %bb.3:
; X64-NEXT: jmp on_less@PLT # TAILCALL
; X64-NEXT: .LBB0_1:
; X64-NEXT: jne .LBB0_2
; X64-NEXT: # %bb.4:
; X64-NEXT: jmp on_equal@PLT # TAILCALL
; X64-NEXT: .LBB0_2:
; X64-NEXT: jl on_less@PLT # TAILCALL
; X64-NEXT: # %bb.1:
; X64-NEXT: je on_equal@PLT # TAILCALL
; X64-NEXT: # %bb.2:
; X64-NEXT: jmp on_greater@PLT # TAILCALL
%3 = icmp slt i32 %0, %1
br i1 %3, label %4, label %5
Expand All @@ -61,27 +53,19 @@ define void @gt_first(i32 %0, i32 %1) {
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
; X86-NEXT: cmpl %eax, %ecx
; X86-NEXT: jge .LBB1_1
; X86-NEXT: # %bb.3:
; X86-NEXT: jmp on_less@PLT # TAILCALL
; X86-NEXT: .LBB1_1:
; X86-NEXT: jle .LBB1_2
; X86-NEXT: # %bb.4:
; X86-NEXT: jmp on_greater@PLT # TAILCALL
; X86-NEXT: .LBB1_2:
; X86-NEXT: jl on_less@PLT # TAILCALL
; X86-NEXT: # %bb.1:
; X86-NEXT: jg on_greater@PLT # TAILCALL
; X86-NEXT: # %bb.2:
; X86-NEXT: jmp on_equal@PLT # TAILCALL
;
; X64-LABEL: gt_first:
; X64: # %bb.0:
; X64-NEXT: cmpl %esi, %edi
; X64-NEXT: jge .LBB1_1
; X64-NEXT: # %bb.3:
; X64-NEXT: jmp on_less@PLT # TAILCALL
; X64-NEXT: .LBB1_1:
; X64-NEXT: jle .LBB1_2
; X64-NEXT: # %bb.4:
; X64-NEXT: jmp on_greater@PLT # TAILCALL
; X64-NEXT: .LBB1_2:
; X64-NEXT: jl on_less@PLT # TAILCALL
; X64-NEXT: # %bb.1:
; X64-NEXT: jg on_greater@PLT # TAILCALL
; X64-NEXT: # %bb.2:
; X64-NEXT: jmp on_equal@PLT # TAILCALL
%3 = icmp slt i32 %0, %1
br i1 %3, label %4, label %5
Expand Down
9 changes: 3 additions & 6 deletions llvm/test/CodeGen/X86/cmp.ll
Original file line number Diff line number Diff line change
Expand Up @@ -729,16 +729,13 @@ define i32 @pr42189(i16 signext %c) {
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: cmpl $32767, %edi # encoding: [0x81,0xff,0xff,0x7f,0x00,0x00]
; CHECK-NEXT: # imm = 0x7FFF
; CHECK-NEXT: jne .LBB45_2 # encoding: [0x75,A]
; CHECK-NEXT: # fixup A - offset: 1, value: .LBB45_2-1, kind: FK_PCRel_1
; CHECK-NEXT: jne f@PLT # TAILCALL
; CHECK-NEXT: # encoding: [0x75,A]
; CHECK-NEXT: # fixup A - offset: 1, value: f@PLT-1, kind: FK_PCRel_1
; CHECK-NEXT: # %bb.1: # %if.then
; CHECK-NEXT: jmp g@PLT # TAILCALL
; CHECK-NEXT: # encoding: [0xeb,A]
; CHECK-NEXT: # fixup A - offset: 1, value: g@PLT-1, kind: FK_PCRel_1
; CHECK-NEXT: .LBB45_2: # %if.end
; CHECK-NEXT: jmp f@PLT # TAILCALL
; CHECK-NEXT: # encoding: [0xeb,A]
; CHECK-NEXT: # fixup A - offset: 1, value: f@PLT-1, kind: FK_PCRel_1
entry:
%cmp = icmp eq i16 %c, 32767
br i1 %cmp, label %if.then, label %if.end
Expand Down
24 changes: 8 additions & 16 deletions llvm/test/CodeGen/X86/comi-flags.ll
Original file line number Diff line number Diff line change
Expand Up @@ -553,10 +553,8 @@ define void @PR38960_eq(<4 x float> %A, <4 x float> %B) {
; SSE-NEXT: setnp %al
; SSE-NEXT: sete %cl
; SSE-NEXT: testb %al, %cl
; SSE-NEXT: je .LBB24_1
; SSE-NEXT: # %bb.2: # %if.then
; SSE-NEXT: jmp foo@PLT # TAILCALL
; SSE-NEXT: .LBB24_1: # %if.end
; SSE-NEXT: jne foo@PLT # TAILCALL
; SSE-NEXT: # %bb.1: # %if.end
; SSE-NEXT: retq
;
; AVX-LABEL: PR38960_eq:
Expand All @@ -565,10 +563,8 @@ define void @PR38960_eq(<4 x float> %A, <4 x float> %B) {
; AVX-NEXT: setnp %al
; AVX-NEXT: sete %cl
; AVX-NEXT: testb %al, %cl
; AVX-NEXT: je .LBB24_1
; AVX-NEXT: # %bb.2: # %if.then
; AVX-NEXT: jmp foo@PLT # TAILCALL
; AVX-NEXT: .LBB24_1: # %if.end
; AVX-NEXT: jne foo@PLT # TAILCALL
; AVX-NEXT: # %bb.1: # %if.end
; AVX-NEXT: retq
entry:
%call = tail call i32 @llvm.x86.sse.comieq.ss(<4 x float> %A, <4 x float> %B) #3
Expand All @@ -590,10 +586,8 @@ define void @PR38960_neq(<4 x float> %A, <4 x float> %B) {
; SSE-NEXT: setp %al
; SSE-NEXT: setne %cl
; SSE-NEXT: orb %al, %cl
; SSE-NEXT: je .LBB25_1
; SSE-NEXT: # %bb.2: # %if.then
; SSE-NEXT: jmp foo@PLT # TAILCALL
; SSE-NEXT: .LBB25_1: # %if.end
; SSE-NEXT: jne foo@PLT # TAILCALL
; SSE-NEXT: # %bb.1: # %if.end
; SSE-NEXT: retq
;
; AVX-LABEL: PR38960_neq:
Expand All @@ -602,10 +596,8 @@ define void @PR38960_neq(<4 x float> %A, <4 x float> %B) {
; AVX-NEXT: setp %al
; AVX-NEXT: setne %cl
; AVX-NEXT: orb %al, %cl
; AVX-NEXT: je .LBB25_1
; AVX-NEXT: # %bb.2: # %if.then
; AVX-NEXT: jmp foo@PLT # TAILCALL
; AVX-NEXT: .LBB25_1: # %if.end
; AVX-NEXT: jne foo@PLT # TAILCALL
; AVX-NEXT: # %bb.1: # %if.end
; AVX-NEXT: retq
entry:
%call = tail call i32 @llvm.x86.sse.comineq.ss(<4 x float> %A, <4 x float> %B) #3
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/CodeGen/X86/extern_weak.ll
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ if.end:

; DARWIN-LABEL: _bar:
; DARWIN: cmpl $0, L_foo$non_lazy_ptr
; DARWIN: jmp _foo ## TAILCALL
; DARWIN: jne _foo ## TAILCALL

; WIN32-LABEL: _bar:
; WIN32: cmpl $0, .refptr._foo
Expand Down
720 changes: 240 additions & 480 deletions llvm/test/CodeGen/X86/fold-rmw-ops.ll

Large diffs are not rendered by default.

18 changes: 6 additions & 12 deletions llvm/test/CodeGen/X86/fp-strict-scalar-cmp-fp16.ll
Original file line number Diff line number Diff line change
Expand Up @@ -1776,29 +1776,23 @@ define void @foo(half %0, half %1) #0 {
; AVX-NEXT: vmovd %eax, %xmm1
; AVX-NEXT: vcvtph2ps %xmm1, %xmm1
; AVX-NEXT: vucomiss %xmm0, %xmm1
; AVX-NEXT: jbe .LBB28_1
; AVX-NEXT: # %bb.2:
; AVX-NEXT: jmp bar@PLT # TAILCALL
; AVX-NEXT: .LBB28_1:
; AVX-NEXT: ja bar@PLT # TAILCALL
; AVX-NEXT: # %bb.1:
; AVX-NEXT: retq
;
; CHECK-32-LABEL: foo:
; CHECK-32: # %bb.0:
; CHECK-32-NEXT: vmovsh {{[0-9]+}}(%esp), %xmm0
; CHECK-32-NEXT: vucomish {{[0-9]+}}(%esp), %xmm0
; CHECK-32-NEXT: jbe .LBB28_1
; CHECK-32-NEXT: # %bb.2:
; CHECK-32-NEXT: jmp bar@PLT # TAILCALL
; CHECK-32-NEXT: .LBB28_1:
; CHECK-32-NEXT: ja bar@PLT # TAILCALL
; CHECK-32-NEXT: # %bb.1:
; CHECK-32-NEXT: retl
;
; CHECK-64-LABEL: foo:
; CHECK-64: # %bb.0:
; CHECK-64-NEXT: vucomish %xmm1, %xmm0
; CHECK-64-NEXT: jbe .LBB28_1
; CHECK-64-NEXT: # %bb.2:
; CHECK-64-NEXT: jmp bar@PLT # TAILCALL
; CHECK-64-NEXT: .LBB28_1:
; CHECK-64-NEXT: ja bar@PLT # TAILCALL
; CHECK-64-NEXT: # %bb.1:
; CHECK-64-NEXT: retq
%3 = call i1 @llvm.experimental.constrained.fcmp.f16( half %0, half %1, metadata !"ogt", metadata !"fpexcept.strict") #0
br i1 %3, label %4, label %5
Expand Down
36 changes: 12 additions & 24 deletions llvm/test/CodeGen/X86/fp-strict-scalar-cmp.ll
Original file line number Diff line number Diff line change
Expand Up @@ -4141,38 +4141,30 @@ define void @foo(float %0, float %1) #0 {
; SSE-32: # %bb.0:
; SSE-32-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
; SSE-32-NEXT: ucomiss {{[0-9]+}}(%esp), %xmm0
; SSE-32-NEXT: jbe .LBB56_1
; SSE-32-NEXT: # %bb.2:
; SSE-32-NEXT: jmp bar # TAILCALL
; SSE-32-NEXT: .LBB56_1:
; SSE-32-NEXT: ja bar # TAILCALL
; SSE-32-NEXT: # %bb.1:
; SSE-32-NEXT: retl
;
; SSE-64-LABEL: foo:
; SSE-64: # %bb.0:
; SSE-64-NEXT: ucomiss %xmm1, %xmm0
; SSE-64-NEXT: jbe .LBB56_1
; SSE-64-NEXT: # %bb.2:
; SSE-64-NEXT: jmp bar # TAILCALL
; SSE-64-NEXT: .LBB56_1:
; SSE-64-NEXT: ja bar # TAILCALL
; SSE-64-NEXT: # %bb.1:
; SSE-64-NEXT: retq
;
; AVX-32-LABEL: foo:
; AVX-32: # %bb.0:
; AVX-32-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero
; AVX-32-NEXT: vucomiss {{[0-9]+}}(%esp), %xmm0
; AVX-32-NEXT: jbe .LBB56_1
; AVX-32-NEXT: # %bb.2:
; AVX-32-NEXT: jmp bar # TAILCALL
; AVX-32-NEXT: .LBB56_1:
; AVX-32-NEXT: ja bar # TAILCALL
; AVX-32-NEXT: # %bb.1:
; AVX-32-NEXT: retl
;
; AVX-64-LABEL: foo:
; AVX-64: # %bb.0:
; AVX-64-NEXT: vucomiss %xmm1, %xmm0
; AVX-64-NEXT: jbe .LBB56_1
; AVX-64-NEXT: # %bb.2:
; AVX-64-NEXT: jmp bar # TAILCALL
; AVX-64-NEXT: .LBB56_1:
; AVX-64-NEXT: ja bar # TAILCALL
; AVX-64-NEXT: # %bb.1:
; AVX-64-NEXT: retq
;
; X87-LABEL: foo:
Expand All @@ -4184,10 +4176,8 @@ define void @foo(float %0, float %1) #0 {
; X87-NEXT: fnstsw %ax
; X87-NEXT: # kill: def $ah killed $ah killed $ax
; X87-NEXT: sahf
; X87-NEXT: jbe .LBB56_1
; X87-NEXT: # %bb.2:
; X87-NEXT: jmp bar # TAILCALL
; X87-NEXT: .LBB56_1:
; X87-NEXT: ja bar # TAILCALL
; X87-NEXT: # %bb.1:
; X87-NEXT: retl
;
; X87-CMOV-LABEL: foo:
Expand All @@ -4197,10 +4187,8 @@ define void @foo(float %0, float %1) #0 {
; X87-CMOV-NEXT: fucompi %st(1), %st
; X87-CMOV-NEXT: fstp %st(0)
; X87-CMOV-NEXT: wait
; X87-CMOV-NEXT: jbe .LBB56_1
; X87-CMOV-NEXT: # %bb.2:
; X87-CMOV-NEXT: jmp bar # TAILCALL
; X87-CMOV-NEXT: .LBB56_1:
; X87-CMOV-NEXT: ja bar # TAILCALL
; X87-CMOV-NEXT: # %bb.1:
; X87-CMOV-NEXT: retl
%3 = call i1 @llvm.experimental.constrained.fcmp.f32( float %0, float %1, metadata !"ogt", metadata !"fpexcept.strict") #0
br i1 %3, label %4, label %5
Expand Down
6 changes: 2 additions & 4 deletions llvm/test/CodeGen/X86/funnel-shift.ll
Original file line number Diff line number Diff line change
Expand Up @@ -1017,10 +1017,8 @@ define void @PR45265(i32 %0, %struct.S* nocapture readonly %1) nounwind {
; X64-AVX2-NEXT: movq (%rsi,%rcx,4), %rcx
; X64-AVX2-NEXT: shrdq $40, %rdi, %rcx
; X64-AVX2-NEXT: cmpq %rax, %rcx
; X64-AVX2-NEXT: jne .LBB46_1
; X64-AVX2-NEXT: # %bb.2:
; X64-AVX2-NEXT: jmp _Z3foov # TAILCALL
; X64-AVX2-NEXT: .LBB46_1:
; X64-AVX2-NEXT: je _Z3foov # TAILCALL
; X64-AVX2-NEXT: # %bb.1:
; X64-AVX2-NEXT: retq
%3 = sext i32 %0 to i64
%4 = getelementptr inbounds %struct.S, %struct.S* %1, i64 %3
Expand Down
3 changes: 1 addition & 2 deletions llvm/test/CodeGen/X86/jump_sign.ll
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@ define i32 @func_f(i32 %X) {
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax
; CHECK-NEXT: incl %eax
; CHECK-NEXT: jns .LBB0_2
; CHECK-NEXT: jns baz@PLT # TAILCALL
; CHECK-NEXT: # %bb.1: # %cond_true
; CHECK-NEXT: calll bar@PLT
; CHECK-NEXT: .LBB0_2: # %cond_next
; CHECK-NEXT: jmp baz@PLT # TAILCALL
entry:
%tmp1 = add i32 %X, 1
Expand Down
12 changes: 4 additions & 8 deletions llvm/test/CodeGen/X86/neg_cmp.ll
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,8 @@ define void @neg_cmp(i32 %x, i32 %y) nounwind {
; CHECK-LABEL: neg_cmp:
; CHECK: # %bb.0:
; CHECK-NEXT: addl %esi, %edi
; CHECK-NEXT: jne .LBB0_1
; CHECK-NEXT: # %bb.2: # %if.then
; CHECK-NEXT: jmp g # TAILCALL
; CHECK-NEXT: .LBB0_1: # %if.end
; CHECK-NEXT: je g # TAILCALL
; CHECK-NEXT: # %bb.1: # %if.end
; CHECK-NEXT: retq
%sub = sub i32 0, %y
%cmp = icmp eq i32 %x, %sub
Expand All @@ -31,10 +29,8 @@ define void @neg_cmp_commuted(i32 %x, i32 %y) nounwind {
; CHECK-LABEL: neg_cmp_commuted:
; CHECK: # %bb.0:
; CHECK-NEXT: addl %esi, %edi
; CHECK-NEXT: jne .LBB1_1
; CHECK-NEXT: # %bb.2: # %if.then
; CHECK-NEXT: jmp g # TAILCALL
; CHECK-NEXT: .LBB1_1: # %if.end
; CHECK-NEXT: je g # TAILCALL
; CHECK-NEXT: # %bb.1: # %if.end
; CHECK-NEXT: retq
%sub = sub i32 0, %y
%cmp = icmp eq i32 %sub, %x
Expand Down
24 changes: 8 additions & 16 deletions llvm/test/CodeGen/X86/or-branch.ll
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,12 @@ define void @foo(i32 %X, i32 %Y, i32 %Z) nounwind {
; JUMP2-LABEL: foo:
; JUMP2: # %bb.0: # %entry
; JUMP2-NEXT: cmpl $5, {{[0-9]+}}(%esp)
; JUMP2-NEXT: jl .LBB0_3
; JUMP2-NEXT: jl bar@PLT # TAILCALL
; JUMP2-NEXT: # %bb.1: # %entry
; JUMP2-NEXT: cmpl $0, {{[0-9]+}}(%esp)
; JUMP2-NEXT: je .LBB0_3
; JUMP2-NEXT: je bar@PLT # TAILCALL
; JUMP2-NEXT: # %bb.2: # %UnifiedReturnBlock
; JUMP2-NEXT: retl
; JUMP2-NEXT: .LBB0_3: # %cond_true
; JUMP2-NEXT: jmp bar@PLT # TAILCALL
;
; JUMP1-LABEL: foo:
; JUMP1: # %bb.0: # %entry
Expand All @@ -22,10 +20,8 @@ define void @foo(i32 %X, i32 %Y, i32 %Z) nounwind {
; JUMP1-NEXT: cmpl $5, {{[0-9]+}}(%esp)
; JUMP1-NEXT: setge %cl
; JUMP1-NEXT: testb %al, %cl
; JUMP1-NEXT: jne .LBB0_1
; JUMP1-NEXT: # %bb.2: # %cond_true
; JUMP1-NEXT: jmp bar@PLT # TAILCALL
; JUMP1-NEXT: .LBB0_1: # %UnifiedReturnBlock
; JUMP1-NEXT: je bar@PLT # TAILCALL
; JUMP1-NEXT: # %bb.1: # %UnifiedReturnBlock
; JUMP1-NEXT: retl
entry:
%tmp1 = icmp eq i32 %X, 0
Expand All @@ -52,10 +48,8 @@ define void @unpredictable(i32 %X, i32 %Y, i32 %Z) nounwind {
; JUMP2-NEXT: cmpl $5, {{[0-9]+}}(%esp)
; JUMP2-NEXT: setge %cl
; JUMP2-NEXT: testb %al, %cl
; JUMP2-NEXT: jne .LBB1_1
; JUMP2-NEXT: # %bb.2: # %cond_true
; JUMP2-NEXT: jmp bar@PLT # TAILCALL
; JUMP2-NEXT: .LBB1_1: # %UnifiedReturnBlock
; JUMP2-NEXT: je bar@PLT # TAILCALL
; JUMP2-NEXT: # %bb.1: # %UnifiedReturnBlock
; JUMP2-NEXT: retl
;
; JUMP1-LABEL: unpredictable:
Expand All @@ -65,10 +59,8 @@ define void @unpredictable(i32 %X, i32 %Y, i32 %Z) nounwind {
; JUMP1-NEXT: cmpl $5, {{[0-9]+}}(%esp)
; JUMP1-NEXT: setge %cl
; JUMP1-NEXT: testb %al, %cl
; JUMP1-NEXT: jne .LBB1_1
; JUMP1-NEXT: # %bb.2: # %cond_true
; JUMP1-NEXT: jmp bar@PLT # TAILCALL
; JUMP1-NEXT: .LBB1_1: # %UnifiedReturnBlock
; JUMP1-NEXT: je bar@PLT # TAILCALL
; JUMP1-NEXT: # %bb.1: # %UnifiedReturnBlock
; JUMP1-NEXT: retl
entry:
%tmp1 = icmp eq i32 %X, 0
Expand Down
54 changes: 18 additions & 36 deletions llvm/test/CodeGen/X86/peep-test-4.ll
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,8 @@ define void @neg(i32 %x) nounwind {
; CHECK-LABEL: neg:
; CHECK: # %bb.0:
; CHECK-NEXT: negl %edi
; CHECK-NEXT: je .LBB0_1
; CHECK-NEXT: # %bb.2: # %bb
; CHECK-NEXT: jmp foo # TAILCALL
; CHECK-NEXT: .LBB0_1: # %return
; CHECK-NEXT: jne foo # TAILCALL
; CHECK-NEXT: # %bb.1: # %return
; CHECK-NEXT: retq
%sub = sub i32 0, %x
%cmp = icmp eq i32 %sub, 0
Expand All @@ -29,10 +27,8 @@ define void @sar(i32 %x) nounwind {
; CHECK-LABEL: sar:
; CHECK: # %bb.0:
; CHECK-NEXT: sarl %edi
; CHECK-NEXT: je .LBB1_1
; CHECK-NEXT: # %bb.2: # %bb
; CHECK-NEXT: jmp foo # TAILCALL
; CHECK-NEXT: .LBB1_1: # %return
; CHECK-NEXT: jne foo # TAILCALL
; CHECK-NEXT: # %bb.1: # %return
; CHECK-NEXT: retq
%ashr = ashr i32 %x, 1
%cmp = icmp eq i32 %ashr, 0
Expand All @@ -50,10 +46,8 @@ define void @shr(i32 %x) nounwind {
; CHECK-LABEL: shr:
; CHECK: # %bb.0:
; CHECK-NEXT: shrl %edi
; CHECK-NEXT: je .LBB2_1
; CHECK-NEXT: # %bb.2: # %bb
; CHECK-NEXT: jmp foo # TAILCALL
; CHECK-NEXT: .LBB2_1: # %return
; CHECK-NEXT: jne foo # TAILCALL
; CHECK-NEXT: # %bb.1: # %return
; CHECK-NEXT: retq
%ashr = lshr i32 %x, 1
%cmp = icmp eq i32 %ashr, 0
Expand All @@ -71,10 +65,8 @@ define void @shri(i32 %x) nounwind {
; CHECK-LABEL: shri:
; CHECK: # %bb.0:
; CHECK-NEXT: shrl $3, %edi
; CHECK-NEXT: je .LBB3_1
; CHECK-NEXT: # %bb.2: # %bb
; CHECK-NEXT: jmp foo # TAILCALL
; CHECK-NEXT: .LBB3_1: # %return
; CHECK-NEXT: jne foo # TAILCALL
; CHECK-NEXT: # %bb.1: # %return
; CHECK-NEXT: retq
%ashr = lshr i32 %x, 3
%cmp = icmp eq i32 %ashr, 0
Expand All @@ -92,10 +84,8 @@ define void @shl(i32 %x) nounwind {
; CHECK-LABEL: shl:
; CHECK: # %bb.0:
; CHECK-NEXT: addl %edi, %edi
; CHECK-NEXT: je .LBB4_1
; CHECK-NEXT: # %bb.2: # %bb
; CHECK-NEXT: jmp foo # TAILCALL
; CHECK-NEXT: .LBB4_1: # %return
; CHECK-NEXT: jne foo # TAILCALL
; CHECK-NEXT: # %bb.1: # %return
; CHECK-NEXT: retq
%shl = shl i32 %x, 1
%cmp = icmp eq i32 %shl, 0
Expand All @@ -113,10 +103,8 @@ define void @shli(i32 %x) nounwind {
; CHECK-LABEL: shli:
; CHECK: # %bb.0:
; CHECK-NEXT: shll $4, %edi
; CHECK-NEXT: je .LBB5_1
; CHECK-NEXT: # %bb.2: # %bb
; CHECK-NEXT: jmp foo # TAILCALL
; CHECK-NEXT: .LBB5_1: # %return
; CHECK-NEXT: jne foo # TAILCALL
; CHECK-NEXT: # %bb.1: # %return
; CHECK-NEXT: retq
%shl = shl i32 %x, 4
%cmp = icmp eq i32 %shl, 0
Expand Down Expand Up @@ -159,10 +147,8 @@ define void @andn(i32 %x, i32 %y) nounwind {
; CHECK-LABEL: andn:
; CHECK: # %bb.0:
; CHECK-NEXT: andnl %esi, %edi, %edi
; CHECK-NEXT: je .LBB8_1
; CHECK-NEXT: # %bb.2: # %bb
; CHECK-NEXT: jmp foo # TAILCALL
; CHECK-NEXT: .LBB8_1: # %return
; CHECK-NEXT: jne foo # TAILCALL
; CHECK-NEXT: # %bb.1: # %return
; CHECK-NEXT: retq
%not = xor i32 %x, -1
%andn = and i32 %y, %not
Expand All @@ -182,10 +168,8 @@ define void @bextr(i32 %x, i32 %y) nounwind {
; CHECK-LABEL: bextr:
; CHECK: # %bb.0:
; CHECK-NEXT: bextrl %esi, %edi, %edi
; CHECK-NEXT: je .LBB9_1
; CHECK-NEXT: # %bb.2: # %bb
; CHECK-NEXT: jmp foo # TAILCALL
; CHECK-NEXT: .LBB9_1: # %return
; CHECK-NEXT: jne foo # TAILCALL
; CHECK-NEXT: # %bb.1: # %return
; CHECK-NEXT: retq
%bextr = tail call i32 @llvm.x86.bmi.bextr.32(i32 %x, i32 %y)
%cmp = icmp eq i32 %bextr, 0
Expand All @@ -204,10 +188,8 @@ define void @popcnt(i32 %x) nounwind {
; CHECK-LABEL: popcnt:
; CHECK: # %bb.0:
; CHECK-NEXT: popcntl %edi, %edi
; CHECK-NEXT: je .LBB10_1
; CHECK-NEXT: # %bb.2: # %bb
; CHECK-NEXT: jmp foo # TAILCALL
; CHECK-NEXT: .LBB10_1: # %return
; CHECK-NEXT: jne foo # TAILCALL
; CHECK-NEXT: # %bb.1: # %return
; CHECK-NEXT: retq
%popcnt = tail call i32 @llvm.ctpop.i32(i32 %x)
%cmp = icmp eq i32 %popcnt, 0
Expand Down
16 changes: 4 additions & 12 deletions llvm/test/CodeGen/X86/pr37025.ll
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@ define void @test_dec_select(ptr nocapture %0, ptr readnone %1) {
; CHECK-NEXT: jne .LBB0_2
; CHECK-NEXT: # %bb.1:
; CHECK-NEXT: testq %rsi, %rsi
; CHECK-NEXT: je .LBB0_2
; CHECK-NEXT: # %bb.3:
; CHECK-NEXT: jmp func2 # TAILCALL
; CHECK-NEXT: jne func2 # TAILCALL
; CHECK-NEXT: .LBB0_2:
; CHECK-NEXT: retq
%3 = atomicrmw sub ptr %0, i64 1 seq_cst
Expand All @@ -49,9 +47,7 @@ define void @test_dec_select_commute(ptr nocapture %0, ptr readnone %1) {
; CHECK-NEXT: je .LBB1_2
; CHECK-NEXT: # %bb.1:
; CHECK-NEXT: testb %al, %al
; CHECK-NEXT: je .LBB1_2
; CHECK-NEXT: # %bb.3:
; CHECK-NEXT: jmp func2 # TAILCALL
; CHECK-NEXT: jne func2 # TAILCALL
; CHECK-NEXT: .LBB1_2:
; CHECK-NEXT: retq
%3 = atomicrmw sub ptr %0, i64 1 seq_cst
Expand All @@ -77,9 +73,7 @@ define void @test_dec_and(ptr nocapture %0, ptr readnone %1) {
; CHECK-NEXT: je .LBB2_2
; CHECK-NEXT: # %bb.1:
; CHECK-NEXT: testb %al, %al
; CHECK-NEXT: je .LBB2_2
; CHECK-NEXT: # %bb.3:
; CHECK-NEXT: jmp func2 # TAILCALL
; CHECK-NEXT: jne func2 # TAILCALL
; CHECK-NEXT: .LBB2_2:
; CHECK-NEXT: retq
%3 = atomicrmw sub ptr %0, i64 1 seq_cst
Expand All @@ -103,9 +97,7 @@ define void @test_dec_and_commute(ptr nocapture %0, ptr readnone %1) {
; CHECK-NEXT: jne .LBB3_2
; CHECK-NEXT: # %bb.1:
; CHECK-NEXT: testq %rsi, %rsi
; CHECK-NEXT: je .LBB3_2
; CHECK-NEXT: # %bb.3:
; CHECK-NEXT: jmp func2 # TAILCALL
; CHECK-NEXT: jne func2 # TAILCALL
; CHECK-NEXT: .LBB3_2:
; CHECK-NEXT: retq
%3 = atomicrmw sub ptr %0, i64 1 seq_cst
Expand Down
4 changes: 1 addition & 3 deletions llvm/test/CodeGen/X86/pr37063.ll
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,9 @@ define void @foo(ptr) {
; CHECK-NEXT: movl (%rdi), %eax
; CHECK-NEXT: andl $6, %eax
; CHECK-NEXT: cmpl $4, %eax
; CHECK-NEXT: jne .LBB0_2
; CHECK-NEXT: jne bar # TAILCALL
; CHECK-NEXT: # %bb.1: # %bb1
; CHECK-NEXT: retq
; CHECK-NEXT: .LBB0_2: # %bb2.i
; CHECK-NEXT: jmp bar # TAILCALL
start:
%1 = load i64, ptr %0, align 8, !range !0
%2 = and i64 %1, 6
Expand Down
16 changes: 4 additions & 12 deletions llvm/test/CodeGen/X86/rd-mod-wr-eflags.ll
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,9 @@ define dso_local void @_Z7releaseP3obj(ptr nocapture %o) nounwind uwtable ssp {
; CHECK-LABEL: _Z7releaseP3obj:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: decq (%rdi)
; CHECK-NEXT: je .LBB0_2
; CHECK-NEXT: je free # TAILCALL
; CHECK-NEXT: # %bb.1: # %return
; CHECK-NEXT: retq
; CHECK-NEXT: .LBB0_2: # %if.end
; CHECK-NEXT: jmp free # TAILCALL
entry:
%0 = load i64, ptr %o, align 8
%dec = add i64 %0, -1
Expand Down Expand Up @@ -112,11 +110,9 @@ define dso_local void @example_dec(ptr %o) nounwind uwtable ssp {
; CHECK-NEXT: jne .LBB3_4
; CHECK-NEXT: # %bb.3: # %if.end2
; CHECK-NEXT: decb 14(%rdi)
; CHECK-NEXT: je .LBB3_5
; CHECK-NEXT: je other # TAILCALL
; CHECK-NEXT: .LBB3_4: # %return
; CHECK-NEXT: retq
; CHECK-NEXT: .LBB3_5: # %if.end4
; CHECK-NEXT: jmp other # TAILCALL
entry:
%0 = load i64, ptr %o, align 8
%dec = add i64 %0, -1
Expand Down Expand Up @@ -173,9 +169,7 @@ define dso_local void @example_inc(ptr %o) nounwind uwtable ssp {
; CHECK-NEXT: jne .LBB4_4
; CHECK-NEXT: # %bb.3: # %if.end2
; CHECK-NEXT: incb 14(%rdi)
; CHECK-NEXT: jne .LBB4_4
; CHECK-NEXT: # %bb.5: # %if.end4
; CHECK-NEXT: jmp other # TAILCALL
; CHECK-NEXT: je other # TAILCALL
; CHECK-NEXT: .LBB4_4: # %return
; CHECK-NEXT: retq
entry:
Expand Down Expand Up @@ -229,11 +223,9 @@ define dso_local void @test3() nounwind ssp {
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq foo(%rip), %rax
; CHECK-NEXT: decq 16(%rax)
; CHECK-NEXT: je .LBB5_2
; CHECK-NEXT: je baz # TAILCALL
; CHECK-NEXT: # %bb.1: # %if.end
; CHECK-NEXT: retq
; CHECK-NEXT: .LBB5_2: # %if.then
; CHECK-NEXT: jmp baz # TAILCALL
entry:
%0 = load ptr, ptr @foo, align 8
%arrayidx = getelementptr inbounds i64, ptr %0, i64 2
Expand Down
60 changes: 20 additions & 40 deletions llvm/test/CodeGen/X86/segmented-stacks.ll
Original file line number Diff line number Diff line change
Expand Up @@ -1720,10 +1720,8 @@ define i32 @test_sibling_call_empty_frame(i32 %x) #0 {
; X86-Linux-LABEL: test_sibling_call_empty_frame:
; X86-Linux: # %bb.0:
; X86-Linux-NEXT: cmpl %gs:48, %esp
; X86-Linux-NEXT: jbe .LBB8_1
; X86-Linux-NEXT: # %bb.2:
; X86-Linux-NEXT: jmp callee@PLT # TAILCALL
; X86-Linux-NEXT: .LBB8_1:
; X86-Linux-NEXT: ja callee@PLT # TAILCALL
; X86-Linux-NEXT: # %bb.1:
; X86-Linux-NEXT: pushl $4
; X86-Linux-NEXT: pushl $0
; X86-Linux-NEXT: calll __morestack
Expand All @@ -1733,10 +1731,8 @@ define i32 @test_sibling_call_empty_frame(i32 %x) #0 {
; X64-Linux-LABEL: test_sibling_call_empty_frame:
; X64-Linux: # %bb.0:
; X64-Linux-NEXT: cmpq %fs:112, %rsp
; X64-Linux-NEXT: jbe .LBB8_1
; X64-Linux-NEXT: # %bb.2:
; X64-Linux-NEXT: jmp callee@PLT # TAILCALL
; X64-Linux-NEXT: .LBB8_1:
; X64-Linux-NEXT: ja callee@PLT # TAILCALL
; X64-Linux-NEXT: # %bb.1:
; X64-Linux-NEXT: movl $0, %r10d
; X64-Linux-NEXT: movl $0, %r11d
; X64-Linux-NEXT: callq __morestack
Expand All @@ -1761,10 +1757,8 @@ define i32 @test_sibling_call_empty_frame(i32 %x) #0 {
; X32ABI-LABEL: test_sibling_call_empty_frame:
; X32ABI: # %bb.0:
; X32ABI-NEXT: cmpl %fs:64, %esp
; X32ABI-NEXT: jbe .LBB8_1
; X32ABI-NEXT: # %bb.2:
; X32ABI-NEXT: jmp callee@PLT # TAILCALL
; X32ABI-NEXT: .LBB8_1:
; X32ABI-NEXT: ja callee@PLT # TAILCALL
; X32ABI-NEXT: # %bb.1:
; X32ABI-NEXT: movl $0, %r10d
; X32ABI-NEXT: movl $0, %r11d
; X32ABI-NEXT: callq __morestack
Expand All @@ -1775,10 +1769,8 @@ define i32 @test_sibling_call_empty_frame(i32 %x) #0 {
; X86-Darwin: ## %bb.0:
; X86-Darwin-NEXT: movl $432, %ecx ## imm = 0x1B0
; X86-Darwin-NEXT: cmpl %gs:(%ecx), %esp
; X86-Darwin-NEXT: jbe LBB8_1
; X86-Darwin-NEXT: ## %bb.2:
; X86-Darwin-NEXT: jmp _callee ## TAILCALL
; X86-Darwin-NEXT: LBB8_1:
; X86-Darwin-NEXT: ja _callee ## TAILCALL
; X86-Darwin-NEXT: ## %bb.1:
; X86-Darwin-NEXT: pushl $4
; X86-Darwin-NEXT: pushl $0
; X86-Darwin-NEXT: calll ___morestack
Expand All @@ -1788,10 +1780,8 @@ define i32 @test_sibling_call_empty_frame(i32 %x) #0 {
; X64-Darwin-LABEL: test_sibling_call_empty_frame:
; X64-Darwin: ## %bb.0:
; X64-Darwin-NEXT: cmpq %gs:816, %rsp
; X64-Darwin-NEXT: jbe LBB8_1
; X64-Darwin-NEXT: ## %bb.2:
; X64-Darwin-NEXT: jmp _callee ## TAILCALL
; X64-Darwin-NEXT: LBB8_1:
; X64-Darwin-NEXT: ja _callee ## TAILCALL
; X64-Darwin-NEXT: ## %bb.1:
; X64-Darwin-NEXT: movl $0, %r10d
; X64-Darwin-NEXT: movl $0, %r11d
; X64-Darwin-NEXT: callq ___morestack
Expand All @@ -1801,10 +1791,8 @@ define i32 @test_sibling_call_empty_frame(i32 %x) #0 {
; X86-MinGW-LABEL: test_sibling_call_empty_frame:
; X86-MinGW: # %bb.0:
; X86-MinGW-NEXT: cmpl %fs:20, %esp
; X86-MinGW-NEXT: jbe LBB8_1
; X86-MinGW-NEXT: # %bb.2:
; X86-MinGW-NEXT: jmp _callee # TAILCALL
; X86-MinGW-NEXT: LBB8_1:
; X86-MinGW-NEXT: ja _callee # TAILCALL
; X86-MinGW-NEXT: # %bb.1:
; X86-MinGW-NEXT: pushl $4
; X86-MinGW-NEXT: pushl $0
; X86-MinGW-NEXT: calll ___morestack
Expand All @@ -1814,10 +1802,8 @@ define i32 @test_sibling_call_empty_frame(i32 %x) #0 {
; X64-FreeBSD-LABEL: test_sibling_call_empty_frame:
; X64-FreeBSD: # %bb.0:
; X64-FreeBSD-NEXT: cmpq %fs:24, %rsp
; X64-FreeBSD-NEXT: jbe .LBB8_1
; X64-FreeBSD-NEXT: # %bb.2:
; X64-FreeBSD-NEXT: jmp callee@PLT # TAILCALL
; X64-FreeBSD-NEXT: .LBB8_1:
; X64-FreeBSD-NEXT: ja callee@PLT # TAILCALL
; X64-FreeBSD-NEXT: # %bb.1:
; X64-FreeBSD-NEXT: movl $0, %r10d
; X64-FreeBSD-NEXT: movl $0, %r11d
; X64-FreeBSD-NEXT: callq __morestack
Expand All @@ -1827,10 +1813,8 @@ define i32 @test_sibling_call_empty_frame(i32 %x) #0 {
; X86-DFlyBSD-LABEL: test_sibling_call_empty_frame:
; X86-DFlyBSD: # %bb.0:
; X86-DFlyBSD-NEXT: cmpl %fs:16, %esp
; X86-DFlyBSD-NEXT: jbe .LBB8_1
; X86-DFlyBSD-NEXT: # %bb.2:
; X86-DFlyBSD-NEXT: jmp callee@PLT # TAILCALL
; X86-DFlyBSD-NEXT: .LBB8_1:
; X86-DFlyBSD-NEXT: ja callee@PLT # TAILCALL
; X86-DFlyBSD-NEXT: # %bb.1:
; X86-DFlyBSD-NEXT: pushl $4
; X86-DFlyBSD-NEXT: pushl $0
; X86-DFlyBSD-NEXT: calll __morestack
Expand All @@ -1840,10 +1824,8 @@ define i32 @test_sibling_call_empty_frame(i32 %x) #0 {
; X64-DFlyBSD-LABEL: test_sibling_call_empty_frame:
; X64-DFlyBSD: # %bb.0:
; X64-DFlyBSD-NEXT: cmpq %fs:32, %rsp
; X64-DFlyBSD-NEXT: jbe .LBB8_1
; X64-DFlyBSD-NEXT: # %bb.2:
; X64-DFlyBSD-NEXT: jmp callee@PLT # TAILCALL
; X64-DFlyBSD-NEXT: .LBB8_1:
; X64-DFlyBSD-NEXT: ja callee@PLT # TAILCALL
; X64-DFlyBSD-NEXT: # %bb.1:
; X64-DFlyBSD-NEXT: movl $0, %r10d
; X64-DFlyBSD-NEXT: movl $0, %r11d
; X64-DFlyBSD-NEXT: callq __morestack
Expand All @@ -1853,10 +1835,8 @@ define i32 @test_sibling_call_empty_frame(i32 %x) #0 {
; X64-MinGW-LABEL: test_sibling_call_empty_frame:
; X64-MinGW: # %bb.0:
; X64-MinGW-NEXT: cmpq %gs:40, %rsp
; X64-MinGW-NEXT: jbe .LBB8_1
; X64-MinGW-NEXT: # %bb.2:
; X64-MinGW-NEXT: jmp callee # TAILCALL
; X64-MinGW-NEXT: .LBB8_1:
; X64-MinGW-NEXT: ja callee # TAILCALL
; X64-MinGW-NEXT: # %bb.1:
; X64-MinGW-NEXT: movl $0, %r10d
; X64-MinGW-NEXT: movl $32, %r11d
; X64-MinGW-NEXT: callq __morestack
Expand Down
48 changes: 16 additions & 32 deletions llvm/test/CodeGen/X86/sibcall.ll
Original file line number Diff line number Diff line change
Expand Up @@ -138,22 +138,18 @@ define dso_local i32 @t6(i32 %x) nounwind ssp {
; X64-LABEL: t6:
; X64: # %bb.0:
; X64-NEXT: cmpl $9, %edi
; X64-NEXT: jg .LBB6_2
; X64-NEXT: jg bar # TAILCALL
; X64-NEXT: # %bb.1: # %bb
; X64-NEXT: decl %edi
; X64-NEXT: jmp t6 # TAILCALL
; X64-NEXT: .LBB6_2: # %bb1
; X64-NEXT: jmp bar # TAILCALL
;
; X32-LABEL: t6:
; X32: # %bb.0:
; X32-NEXT: cmpl $9, %edi
; X32-NEXT: jg .LBB6_2
; X32-NEXT: jg bar # TAILCALL
; X32-NEXT: # %bb.1: # %bb
; X32-NEXT: decl %edi
; X32-NEXT: jmp t6 # TAILCALL
; X32-NEXT: .LBB6_2: # %bb1
; X32-NEXT: jmp bar # TAILCALL
%t0 = icmp slt i32 %x, 10
br i1 %t0, label %bb, label %bb1

Expand Down Expand Up @@ -260,30 +256,24 @@ define dso_local i32 @t11(i32 %x, i32 %y, i32 %z.0, i32 %z.1, i32 %z.2) nounwind
; X86-LABEL: t11:
; X86: # %bb.0: # %entry
; X86-NEXT: cmpl $0, {{[0-9]+}}(%esp)
; X86-NEXT: je .LBB11_1
; X86-NEXT: # %bb.2: # %bb
; X86-NEXT: jmp foo5 # TAILCALL
; X86-NEXT: .LBB11_1: # %bb6
; X86-NEXT: jne foo5 # TAILCALL
; X86-NEXT: # %bb.1: # %bb6
; X86-NEXT: xorl %eax, %eax
; X86-NEXT: retl
;
; X64-LABEL: t11:
; X64: # %bb.0: # %entry
; X64-NEXT: testl %edi, %edi
; X64-NEXT: je .LBB11_1
; X64-NEXT: # %bb.2: # %bb
; X64-NEXT: jmp foo5 # TAILCALL
; X64-NEXT: .LBB11_1: # %bb6
; X64-NEXT: jne foo5 # TAILCALL
; X64-NEXT: # %bb.1: # %bb6
; X64-NEXT: xorl %eax, %eax
; X64-NEXT: retq
;
; X32-LABEL: t11:
; X32: # %bb.0: # %entry
; X32-NEXT: testl %edi, %edi
; X32-NEXT: je .LBB11_1
; X32-NEXT: # %bb.2: # %bb
; X32-NEXT: jmp foo5 # TAILCALL
; X32-NEXT: .LBB11_1: # %bb6
; X32-NEXT: jne foo5 # TAILCALL
; X32-NEXT: # %bb.1: # %bb6
; X32-NEXT: xorl %eax, %eax
; X32-NEXT: retq
entry:
Expand All @@ -306,30 +296,24 @@ define dso_local i32 @t12(i32 %x, i32 %y, ptr byval(%struct.t) align 4 %z) nounw
; X86-LABEL: t12:
; X86: # %bb.0: # %entry
; X86-NEXT: cmpl $0, {{[0-9]+}}(%esp)
; X86-NEXT: je .LBB12_1
; X86-NEXT: # %bb.2: # %bb
; X86-NEXT: jmp foo6 # TAILCALL
; X86-NEXT: .LBB12_1: # %bb2
; X86-NEXT: jne foo6 # TAILCALL
; X86-NEXT: # %bb.1: # %bb2
; X86-NEXT: xorl %eax, %eax
; X86-NEXT: retl
;
; X64-LABEL: t12:
; X64: # %bb.0: # %entry
; X64-NEXT: testl %edi, %edi
; X64-NEXT: je .LBB12_1
; X64-NEXT: # %bb.2: # %bb
; X64-NEXT: jmp foo6 # TAILCALL
; X64-NEXT: .LBB12_1: # %bb2
; X64-NEXT: jne foo6 # TAILCALL
; X64-NEXT: # %bb.1: # %bb2
; X64-NEXT: xorl %eax, %eax
; X64-NEXT: retq
;
; X32-LABEL: t12:
; X32: # %bb.0: # %entry
; X32-NEXT: testl %edi, %edi
; X32-NEXT: je .LBB12_1
; X32-NEXT: # %bb.2: # %bb
; X32-NEXT: jmp foo6 # TAILCALL
; X32-NEXT: .LBB12_1: # %bb2
; X32-NEXT: jne foo6 # TAILCALL
; X32-NEXT: # %bb.1: # %bb2
; X32-NEXT: xorl %eax, %eax
; X32-NEXT: retq
entry:
Expand Down Expand Up @@ -984,11 +968,11 @@ define ccc void @t22_non_sret_to_sret(ptr %agg.result) nounwind {
;
; X64-LABEL: t22_non_sret_to_sret:
; X64: # %bb.0:
; X64-NEXT: jmp t22_f_sret@PLT # TAILCALL
; X64-NEXT: jmp t22_f_sret@PLT # TAILCALL
;
; X32-LABEL: t22_non_sret_to_sret:
; X32: # %bb.0:
; X32-NEXT: jmp t22_f_sret@PLT # TAILCALL
; X32-NEXT: jmp t22_f_sret@PLT # TAILCALL
tail call ccc void @t22_f_sret(ptr noalias sret(%struct.foo) %agg.result) nounwind
ret void
}
Expand Down
20 changes: 6 additions & 14 deletions llvm/test/CodeGen/X86/slow-incdec.ll
Original file line number Diff line number Diff line change
Expand Up @@ -82,20 +82,16 @@ define void @cond_ae_to_cond_ne(ptr %p) nounwind {
; INCDEC: # %bb.0: # %entry
; INCDEC-NEXT: movl {{[0-9]+}}(%esp), %eax
; INCDEC-NEXT: incl (%eax)
; INCDEC-NEXT: jne .LBB6_1
; INCDEC-NEXT: # %bb.2: # %if.end4
; INCDEC-NEXT: jmp other@PLT # TAILCALL
; INCDEC-NEXT: .LBB6_1: # %return
; INCDEC-NEXT: je other@PLT # TAILCALL
; INCDEC-NEXT: # %bb.1: # %return
; INCDEC-NEXT: retl
;
; ADD-LABEL: cond_ae_to_cond_ne:
; ADD: # %bb.0: # %entry
; ADD-NEXT: movl {{[0-9]+}}(%esp), %eax
; ADD-NEXT: addl $1, (%eax)
; ADD-NEXT: jne .LBB6_1
; ADD-NEXT: # %bb.2: # %if.end4
; ADD-NEXT: jmp other@PLT # TAILCALL
; ADD-NEXT: .LBB6_1: # %return
; ADD-NEXT: je other@PLT # TAILCALL
; ADD-NEXT: # %bb.1: # %return
; ADD-NEXT: retl
entry:
%t0 = load i32, ptr %p, align 8
Expand Down Expand Up @@ -129,11 +125,9 @@ define void @test_tail_call(ptr %ptr) nounwind {
; INCDEC-NEXT: incb a
; INCDEC-NEXT: sete d
; INCDEC-NEXT: testb %al, %al
; INCDEC-NEXT: jne .LBB7_2
; INCDEC-NEXT: jne external_b@PLT # TAILCALL
; INCDEC-NEXT: # %bb.1: # %then
; INCDEC-NEXT: jmp external_a@PLT # TAILCALL
; INCDEC-NEXT: .LBB7_2: # %else
; INCDEC-NEXT: jmp external_b@PLT # TAILCALL
;
; ADD-LABEL: test_tail_call:
; ADD: # %bb.0: # %entry
Expand All @@ -143,11 +137,9 @@ define void @test_tail_call(ptr %ptr) nounwind {
; ADD-NEXT: addb $1, a
; ADD-NEXT: sete d
; ADD-NEXT: testb %al, %al
; ADD-NEXT: jne .LBB7_2
; ADD-NEXT: jne external_b@PLT # TAILCALL
; ADD-NEXT: # %bb.1: # %then
; ADD-NEXT: jmp external_a@PLT # TAILCALL
; ADD-NEXT: .LBB7_2: # %else
; ADD-NEXT: jmp external_b@PLT # TAILCALL
entry:
%val = load i32, ptr %ptr
%add_ov = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val, i32 1)
Expand Down
16 changes: 4 additions & 12 deletions llvm/test/CodeGen/X86/sqrt-partial.ll
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,19 @@ define float @f(float %val) nounwind {
; SSE: # %bb.0:
; SSE-NEXT: xorps %xmm1, %xmm1
; SSE-NEXT: ucomiss %xmm1, %xmm0
; SSE-NEXT: jb .LBB0_2
; SSE-NEXT: jb sqrtf # TAILCALL
; SSE-NEXT: # %bb.1: # %.split
; SSE-NEXT: sqrtss %xmm0, %xmm0
; SSE-NEXT: retq
; SSE-NEXT: .LBB0_2: # %call.sqrt
; SSE-NEXT: jmp sqrtf # TAILCALL
;
; AVX-LABEL: f:
; AVX: # %bb.0:
; AVX-NEXT: vxorps %xmm1, %xmm1, %xmm1
; AVX-NEXT: vucomiss %xmm1, %xmm0
; AVX-NEXT: jb .LBB0_2
; AVX-NEXT: jb sqrtf # TAILCALL
; AVX-NEXT: # %bb.1: # %.split
; AVX-NEXT: vsqrtss %xmm0, %xmm0, %xmm0
; AVX-NEXT: retq
; AVX-NEXT: .LBB0_2: # %call.sqrt
; AVX-NEXT: jmp sqrtf # TAILCALL
%res = tail call float @sqrtf(float %val)
ret float %res
}
Expand All @@ -40,23 +36,19 @@ define double @d(double %val) nounwind {
; SSE: # %bb.0:
; SSE-NEXT: xorpd %xmm1, %xmm1
; SSE-NEXT: ucomisd %xmm1, %xmm0
; SSE-NEXT: jb .LBB1_2
; SSE-NEXT: jb sqrt # TAILCALL
; SSE-NEXT: # %bb.1: # %.split
; SSE-NEXT: sqrtsd %xmm0, %xmm0
; SSE-NEXT: retq
; SSE-NEXT: .LBB1_2: # %call.sqrt
; SSE-NEXT: jmp sqrt # TAILCALL
;
; AVX-LABEL: d:
; AVX: # %bb.0:
; AVX-NEXT: vxorpd %xmm1, %xmm1, %xmm1
; AVX-NEXT: vucomisd %xmm1, %xmm0
; AVX-NEXT: jb .LBB1_2
; AVX-NEXT: jb sqrt # TAILCALL
; AVX-NEXT: # %bb.1: # %.split
; AVX-NEXT: vsqrtsd %xmm0, %xmm0, %xmm0
; AVX-NEXT: retq
; AVX-NEXT: .LBB1_2: # %call.sqrt
; AVX-NEXT: jmp sqrt # TAILCALL
%res = tail call double @sqrt(double %val)
ret double %res
}
Expand Down
8 changes: 2 additions & 6 deletions llvm/test/CodeGen/X86/switch-bt.ll
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,7 @@ define void @test2(i32 %x) nounwind ssp {
; CHECK-NEXT: # %bb.1: # %entry
; CHECK-NEXT: movl $91, %eax
; CHECK-NEXT: btl %edi, %eax
; CHECK-NEXT: jae .LBB1_2
; CHECK-NEXT: # %bb.3: # %if.then
; CHECK-NEXT: jmp bar@PLT # TAILCALL
; CHECK-NEXT: jb bar@PLT # TAILCALL
; CHECK-NEXT: .LBB1_2: # %if.end
; CHECK-NEXT: retq

Expand Down Expand Up @@ -118,9 +116,7 @@ define void @test3(i32 %x) nounwind {
; CHECK-NEXT: ja .LBB2_2
; CHECK-NEXT: # %bb.1:
; CHECK-NEXT: cmpl $4, %edi
; CHECK-NEXT: je .LBB2_2
; CHECK-NEXT: # %bb.3: # %if.then
; CHECK-NEXT: jmp bar@PLT # TAILCALL
; CHECK-NEXT: jne bar@PLT # TAILCALL
; CHECK-NEXT: .LBB2_2: # %if.end
; CHECK-NEXT: retq
switch i32 %x, label %if.end [
Expand Down
19 changes: 9 additions & 10 deletions llvm/test/CodeGen/X86/tail-opts.ll
Original file line number Diff line number Diff line change
Expand Up @@ -850,28 +850,27 @@ define dso_local void @bfi_new_block_pgso(i32 %c) nounwind {
; CHECK-LABEL: bfi_new_block_pgso:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: testl %edi, %edi
; CHECK-NEXT: je .LBB14_4
; CHECK-NEXT: je .LBB14_6
; CHECK-NEXT: # %bb.1: # %bb1
; CHECK-NEXT: pushq %rax
; CHECK-NEXT: cmpl $16, %edi
; CHECK-NEXT: je .LBB14_6
; CHECK-NEXT: je .LBB14_3
; CHECK-NEXT: # %bb.2: # %bb1
; CHECK-NEXT: cmpl $17, %edi
; CHECK-NEXT: je .LBB14_7
; CHECK-NEXT: # %bb.3: # %bb4
; CHECK-NEXT: je .LBB14_4
; CHECK-NEXT: # %bb.5: # %bb4
; CHECK-NEXT: popq %rax
; CHECK-NEXT: jmp tail_call_me # TAILCALL
; CHECK-NEXT: .LBB14_4: # %bb5
; CHECK-NEXT: .LBB14_6: # %bb5
; CHECK-NEXT: cmpl $128, %edi
; CHECK-NEXT: jne .LBB14_8
; CHECK-NEXT: # %bb.5: # %return
; CHECK-NEXT: jne tail_call_me # TAILCALL
; CHECK-NEXT: # %bb.7: # %return
; CHECK-NEXT: retq
; CHECK-NEXT: .LBB14_6: # %bb3
; CHECK-NEXT: .LBB14_3: # %bb3
; CHECK-NEXT: movl $0, GV(%rip)
; CHECK-NEXT: .LBB14_7: # %bb4
; CHECK-NEXT: .LBB14_4: # %bb4
; CHECK-NEXT: callq func
; CHECK-NEXT: popq %rax
; CHECK-NEXT: .LBB14_8: # %bb6
; CHECK-NEXT: jmp tail_call_me # TAILCALL
entry:
%0 = icmp eq i32 %c, 0
Expand Down
10 changes: 4 additions & 6 deletions llvm/test/CodeGen/X86/tailcall-cgp-dup.ll
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ declare ptr @bar(ptr) uwtable optsize noinline ssp
define hidden ptr @thingWithValue(ptr %self) uwtable ssp {
entry:
; CHECK-LABEL: thingWithValue:
; CHECK: jmp _bar
; CHECK: je _bar
br i1 undef, label %if.then.i, label %if.else.i

if.then.i: ; preds = %entry
Expand All @@ -92,7 +92,7 @@ someThingWithValue.exit: ; preds = %if.else.i, %if.then
declare zeroext i1 @foo_i1()

; CHECK-LABEL: zext_i1
; CHECK: jmp _foo_i1
; CHECK: je _foo_i1
define zeroext i1 @zext_i1(i1 %k) {
entry:
br i1 %k, label %land.end, label %land.rhs
Expand Down Expand Up @@ -123,10 +123,8 @@ define ptr @f_ret8(ptr %obj) nounwind {
; CHECK-LABEL: f_ret8:
; CHECK: ## %bb.0: ## %entry
; CHECK-NEXT: testq %rdi, %rdi
; CHECK-NEXT: je LBB3_1
; CHECK-NEXT: ## %bb.2: ## %if.then
; CHECK-NEXT: jmp _g_ret32 ## TAILCALL
; CHECK-NEXT: LBB3_1: ## %return
; CHECK-NEXT: jne _g_ret32 ## TAILCALL
; CHECK-NEXT: ## %bb.1: ## %return
; CHECK-NEXT: movq %rdi, %rax
; CHECK-NEXT: retq
entry:
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/CodeGen/X86/tailcall-extract.ll
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
; containing call. And later tail call can be generated.

; CHECK-LABEL: test1:
; CHECK: je foo # TAILCALL
; CHECK: jmp bar # TAILCALL
; CHECK: jmp foo # TAILCALL

; OPT-LABEL: test1
; OPT: if.then.i:
Expand Down Expand Up @@ -96,8 +96,8 @@ exit:
; offset, so the exit block can still be duplicated, and tail call generated.

; CHECK-LABEL: test3:
; CHECK: je qux # TAILCALL
; CHECK: jmp baz # TAILCALL
; CHECK: jmp qux # TAILCALL

; OPT-LABEL: test3
; OPT: if.then.i:
Expand Down
18 changes: 6 additions & 12 deletions llvm/test/CodeGen/X86/xor-icmp.ll
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,17 @@ define i32 @t(i32 %a, i32 %b) nounwind ssp {
; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax
; X86-NEXT: xorb {{[0-9]+}}(%esp), %al
; X86-NEXT: testb $64, %al
; X86-NEXT: je .LBB0_1
; X86-NEXT: # %bb.2: # %bb1
; X86-NEXT: jmp bar # TAILCALL
; X86-NEXT: .LBB0_1: # %bb
; X86-NEXT: jne bar # TAILCALL
; X86-NEXT: # %bb.1: # %bb
; X86-NEXT: jmp foo # TAILCALL
;
; X64-LABEL: t:
; X64: # %bb.0: # %entry
; X64-NEXT: xorl %esi, %edi
; X64-NEXT: xorl %eax, %eax
; X64-NEXT: testl $16384, %edi # imm = 0x4000
; X64-NEXT: je .LBB0_1
; X64-NEXT: # %bb.2: # %bb1
; X64-NEXT: jmp bar # TAILCALL
; X64-NEXT: .LBB0_1: # %bb
; X64-NEXT: jne bar # TAILCALL
; X64-NEXT: # %bb.1: # %bb
; X64-NEXT: jmp foo # TAILCALL
entry:
%0 = and i32 %a, 16384
Expand Down Expand Up @@ -54,10 +50,8 @@ define i32 @t2(i32 %x, i32 %y) nounwind ssp {
; X86-NEXT: cmpl $0, {{[0-9]+}}(%esp)
; X86-NEXT: sete %cl
; X86-NEXT: cmpb %al, %cl
; X86-NEXT: je .LBB1_1
; X86-NEXT: # %bb.2: # %bb
; X86-NEXT: jmp foo # TAILCALL
; X86-NEXT: .LBB1_1: # %return
; X86-NEXT: jne foo # TAILCALL
; X86-NEXT: # %bb.1: # %return
; X86-NEXT: retl
;
; X64-LABEL: t2:
Expand Down
226 changes: 222 additions & 4 deletions llvm/test/Transforms/InstCombine/icmp-mul.ll
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -passes=instcombine -S | FileCheck %s

declare void @llvm.assume(i1)
declare void @use(i8)
declare void @usev2xi8(<2 x i8>)


define i1 @squared_nsw_eq0(i5 %x) {
; CHECK-LABEL: @squared_nsw_eq0(
Expand Down Expand Up @@ -421,8 +424,7 @@ define i1 @sgt_mulzero(i8 %x) {

define i1 @eq_rem_zero_nonuw(i8 %x) {
; CHECK-LABEL: @eq_rem_zero_nonuw(
; CHECK-NEXT: [[A:%.*]] = mul i8 [[X:%.*]], 5
; CHECK-NEXT: [[B:%.*]] = icmp eq i8 [[A]], 20
; CHECK-NEXT: [[B:%.*]] = icmp eq i8 [[X:%.*]], 4
; CHECK-NEXT: ret i1 [[B]]
;
%a = mul i8 %x, 5
Expand All @@ -432,8 +434,7 @@ define i1 @eq_rem_zero_nonuw(i8 %x) {

define i1 @ne_rem_zero_nonuw(i8 %x) {
; CHECK-LABEL: @ne_rem_zero_nonuw(
; CHECK-NEXT: [[A:%.*]] = mul i8 [[X:%.*]], 5
; CHECK-NEXT: [[B:%.*]] = icmp ne i8 [[A]], 30
; CHECK-NEXT: [[B:%.*]] = icmp ne i8 [[X:%.*]], 6
; CHECK-NEXT: ret i1 [[B]]
;
%a = mul i8 %x, 5
Expand Down Expand Up @@ -956,3 +957,220 @@ define i1 @splat_mul_unknown_lz(i32 %x) {
%r = icmp eq i128 %s, 0
ret i1 %r
}

define i1 @mul_oddC_overflow_eq(i8 %v) {
; CHECK-LABEL: @mul_oddC_overflow_eq(
; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[V:%.*]], 5
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[MUL]], 101
; CHECK-NEXT: ret i1 [[CMP]]
;
%mul = mul i8 %v, 5
%cmp = icmp eq i8 %mul, 101
ret i1 %cmp
}

define i1 @mul_oddC_eq_nomod(i8 %v) {
; CHECK-LABEL: @mul_oddC_eq_nomod(
; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[V:%.*]], 3
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[MUL]], 34
; CHECK-NEXT: ret i1 [[CMP]]
;
%mul = mul i8 %v, 3
%cmp = icmp eq i8 %mul, 34
ret i1 %cmp
}

define i1 @mul_evenC_ne(i8 %v) {
; CHECK-LABEL: @mul_evenC_ne(
; CHECK-NEXT: [[MUL:%.*]] = mul i8 [[V:%.*]], 6
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[MUL]], 36
; CHECK-NEXT: ret i1 [[CMP]]
;
%mul = mul i8 %v, 6
%cmp = icmp ne i8 %mul, 36
ret i1 %cmp
}

define <2 x i1> @mul_oddC_ne_vec(<2 x i8> %v) {
; CHECK-LABEL: @mul_oddC_ne_vec(
; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i8> [[V:%.*]], <i8 4, i8 4>
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%mul = mul <2 x i8> %v, <i8 3, i8 3>
%cmp = icmp ne <2 x i8> %mul, <i8 12, i8 12>
ret <2 x i1> %cmp
}

define <2 x i1> @mul_oddC_ne_nosplat_vec(<2 x i8> %v) {
; CHECK-LABEL: @mul_oddC_ne_nosplat_vec(
; CHECK-NEXT: [[MUL:%.*]] = mul <2 x i8> [[V:%.*]], <i8 3, i8 5>
; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i8> [[MUL]], <i8 12, i8 15>
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%mul = mul <2 x i8> %v, <i8 3, i8 5>
%cmp = icmp ne <2 x i8> %mul, <i8 12, i8 15>
ret <2 x i1> %cmp
}

define i1 @mul_nsuw_xy_z_maybe_zero_eq(i8 %x, i8 %y, i8 %z) {
; CHECK-LABEL: @mul_nsuw_xy_z_maybe_zero_eq(
; CHECK-NEXT: [[MULX:%.*]] = mul nuw nsw i8 [[X:%.*]], [[Z:%.*]]
; CHECK-NEXT: [[MULY:%.*]] = mul nuw nsw i8 [[Y:%.*]], [[Z]]
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[MULX]], [[MULY]]
; CHECK-NEXT: ret i1 [[CMP]]
;
%mulx = mul nsw nuw i8 %x, %z
%muly = mul nsw nuw i8 %y, %z
%cmp = icmp eq i8 %mulx, %muly
ret i1 %cmp
}

define i1 @mul_xy_z_assumenozero_ne(i8 %x, i8 %y, i8 %z) {
; CHECK-LABEL: @mul_xy_z_assumenozero_ne(
; CHECK-NEXT: [[NZ:%.*]] = icmp ne i8 [[Z:%.*]], 0
; CHECK-NEXT: call void @llvm.assume(i1 [[NZ]])
; CHECK-NEXT: [[MULX:%.*]] = mul i8 [[X:%.*]], [[Z]]
; CHECK-NEXT: [[MULY:%.*]] = mul i8 [[Y:%.*]], [[Z]]
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[MULY]], [[MULX]]
; CHECK-NEXT: ret i1 [[CMP]]
;
%nz = icmp ne i8 %z, 0
call void @llvm.assume(i1 %nz)
%mulx = mul i8 %x, %z
%muly = mul i8 %y, %z
%cmp = icmp ne i8 %muly, %mulx
ret i1 %cmp
}

define i1 @mul_xy_z_assumeodd_eq(i8 %x, i8 %y, i8 %z) {
; CHECK-LABEL: @mul_xy_z_assumeodd_eq(
; CHECK-NEXT: [[LB:%.*]] = and i8 [[Z:%.*]], 1
; CHECK-NEXT: [[NZ:%.*]] = icmp ne i8 [[LB]], 0
; CHECK-NEXT: call void @llvm.assume(i1 [[NZ]])
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: ret i1 [[CMP]]
;
%lb = and i8 %z, 1
%nz = icmp ne i8 %lb, 0
call void @llvm.assume(i1 %nz)
%mulx = mul i8 %x, %z
%muly = mul i8 %z, %y
%cmp = icmp eq i8 %mulx, %muly
ret i1 %cmp
}

define <2 x i1> @reused_mul_nsw_xy_z_setnonzero_vec_ne(<2 x i8> %x, <2 x i8> %y, <2 x i8> %zi) {
; CHECK-LABEL: @reused_mul_nsw_xy_z_setnonzero_vec_ne(
; CHECK-NEXT: [[Z:%.*]] = or <2 x i8> [[ZI:%.*]], <i8 4, i8 4>
; CHECK-NEXT: [[MULY:%.*]] = mul nsw <2 x i8> [[Z]], [[Y:%.*]]
; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i8> [[Y]], [[X:%.*]]
; CHECK-NEXT: call void @usev2xi8(<2 x i8> [[MULY]])
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%z = or <2 x i8> %zi, <i8 4, i8 4>
%mulx = mul nsw <2 x i8> %z, %x
%muly = mul nsw <2 x i8> %y, %z
%cmp = icmp ne <2 x i8> %muly, %mulx
call void @usev2xi8(<2 x i8> %muly)
ret <2 x i1> %cmp
}

define i1 @mul_mixed_nuw_nsw_xy_z_setodd_ult(i8 %x, i8 %y, i8 %zi) {
; CHECK-LABEL: @mul_mixed_nuw_nsw_xy_z_setodd_ult(
; CHECK-NEXT: [[Z:%.*]] = or i8 [[ZI:%.*]], 1
; CHECK-NEXT: [[MULX:%.*]] = mul nsw i8 [[Z]], [[X:%.*]]
; CHECK-NEXT: [[MULY:%.*]] = mul nuw nsw i8 [[Z]], [[Y:%.*]]
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[MULX]], [[MULY]]
; CHECK-NEXT: ret i1 [[CMP]]
;
%z = or i8 %zi, 1
%mulx = mul nsw i8 %x, %z
%muly = mul nuw nsw i8 %y, %z
%cmp = icmp ult i8 %mulx, %muly
ret i1 %cmp
}

define i1 @mul_nuw_xy_z_assumenonzero_uge(i8 %x, i8 %y, i8 %z) {
; CHECK-LABEL: @mul_nuw_xy_z_assumenonzero_uge(
; CHECK-NEXT: [[NZ:%.*]] = icmp ne i8 [[Z:%.*]], 0
; CHECK-NEXT: call void @llvm.assume(i1 [[NZ]])
; CHECK-NEXT: [[MULX:%.*]] = mul nuw i8 [[X:%.*]], [[Z]]
; CHECK-NEXT: [[CMP:%.*]] = icmp uge i8 [[Y:%.*]], [[X]]
; CHECK-NEXT: call void @use(i8 [[MULX]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%nz = icmp ne i8 %z, 0
call void @llvm.assume(i1 %nz)
%mulx = mul nuw i8 %x, %z
%muly = mul nuw i8 %y, %z
%cmp = icmp uge i8 %muly, %mulx
call void @use(i8 %mulx)
ret i1 %cmp
}

define <2 x i1> @mul_nuw_xy_z_setnonzero_vec_eq(<2 x i8> %x, <2 x i8> %y, <2 x i8> %zi) {
; CHECK-LABEL: @mul_nuw_xy_z_setnonzero_vec_eq(
; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i8> [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%z = or <2 x i8> %zi, <i8 41, i8 12>
%mulx = mul nuw <2 x i8> %z, %x
%muly = mul nuw <2 x i8> %z, %y
%cmp = icmp eq <2 x i8> %mulx, %muly
ret <2 x i1> %cmp
}

define i1 @mul_nuw_xy_z_brnonzero_ult(i8 %x, i8 %y, i8 %z) {
; CHECK-LABEL: @mul_nuw_xy_z_brnonzero_ult(
; CHECK-NEXT: [[NZ_NOT:%.*]] = icmp eq i8 [[Z:%.*]], 0
; CHECK-NEXT: br i1 [[NZ_NOT]], label [[FALSE:%.*]], label [[TRUE:%.*]]
; CHECK: true:
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[Y:%.*]], [[X:%.*]]
; CHECK-NEXT: ret i1 [[CMP]]
; CHECK: false:
; CHECK-NEXT: call void @use(i8 [[Z]])
; CHECK-NEXT: ret i1 true
;
%nz = icmp ne i8 %z, 0
br i1 %nz, label %true, label %false
true:
%mulx = mul nuw i8 %x, %z
%muly = mul nuw i8 %y, %z
%cmp = icmp ult i8 %muly, %mulx
ret i1 %cmp
false:
call void @use(i8 %z)
ret i1 true
}

define i1 @reused_mul_nuw_xy_z_selectnonzero_ugt(i8 %x, i8 %y, i8 %z) {
; CHECK-LABEL: @reused_mul_nuw_xy_z_selectnonzero_ugt(
; CHECK-NEXT: [[NZ_NOT:%.*]] = icmp eq i8 [[Z:%.*]], 0
; CHECK-NEXT: [[MULX:%.*]] = mul nuw i8 [[X:%.*]], [[Z]]
; CHECK-NEXT: [[MULY:%.*]] = mul nuw i8 [[Y:%.*]], [[Z]]
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[MULY]], [[MULX]]
; CHECK-NEXT: [[R:%.*]] = select i1 [[NZ_NOT]], i1 true, i1 [[CMP]]
; CHECK-NEXT: ret i1 [[R]]
;
%nz = icmp ne i8 %z, 0
%mulx = mul nuw i8 %x, %z
%muly = mul nuw i8 %y, %z
%cmp = icmp ugt i8 %muly, %mulx
%r = select i1 %nz, i1 %cmp, i1 true
ret i1 %r
}

define <2 x i1> @mul_mixed_nsw_nuw_xy_z_setnonzero_vec_ule(<2 x i8> %x, <2 x i8> %y, <2 x i8> %zi) {
; CHECK-LABEL: @mul_mixed_nsw_nuw_xy_z_setnonzero_vec_ule(
; CHECK-NEXT: [[Z:%.*]] = or <2 x i8> [[ZI:%.*]], <i8 1, i8 3>
; CHECK-NEXT: [[MULX:%.*]] = mul nuw <2 x i8> [[Z]], [[X:%.*]]
; CHECK-NEXT: [[MULY:%.*]] = mul nsw <2 x i8> [[Z]], [[Y:%.*]]
; CHECK-NEXT: [[CMP:%.*]] = icmp ule <2 x i8> [[MULY]], [[MULX]]
; CHECK-NEXT: ret <2 x i1> [[CMP]]
;
%z = or <2 x i8> %zi, <i8 1, i8 3>
%mulx = mul nuw <2 x i8> %x, %z
%muly = mul nsw <2 x i8> %z, %y
%cmp = icmp ule <2 x i8> %muly, %mulx
ret <2 x i1> %cmp
}