diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index cad3ea4716db3..0d79e4eb3f75a 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -23816,6 +23816,20 @@ SDValue X86TargetLowering::emitFlagsForSetcc(SDValue Op0, SDValue Op1, } } + // Look for X == INT_MIN or X != INT_MIN. We can use NEG and test for + // overflow. + if (isMinSignedConstant(Op1)) { + EVT VT = Op0.getValueType(); + if (VT == MVT::i32 || VT == MVT::i64 || Op0->hasOneUse()) { + SDVTList CmpVTs = DAG.getVTList(VT, MVT::i32); + X86::CondCode CondCode = CC == ISD::SETEQ ? X86::COND_O : X86::COND_NO; + X86CC = DAG.getTargetConstant(CondCode, dl, MVT::i8); + SDValue Neg = DAG.getNode(X86ISD::SUB, dl, CmpVTs, + DAG.getConstant(0, dl, VT), Op0); + return SDValue(Neg.getNode(), 1); + } + } + // Try to use the carry flag from the add in place of an separate CMP for: // (seteq (add X, -1), -1). Similar for setne. if (isAllOnesConstant(Op1) && Op0.getOpcode() == ISD::ADD && diff --git a/llvm/test/CodeGen/X86/2008-06-16-SubregsBug.ll b/llvm/test/CodeGen/X86/2008-06-16-SubregsBug.ll index feaa38a7600a2..00ffea903079e 100644 --- a/llvm/test/CodeGen/X86/2008-06-16-SubregsBug.ll +++ b/llvm/test/CodeGen/X86/2008-06-16-SubregsBug.ll @@ -8,8 +8,8 @@ define i16 @test(ptr %tmp179) nounwind { ; CHECK-NEXT: movzwl (%eax), %eax ; CHECK-NEXT: movl %eax, %ecx ; CHECK-NEXT: andl $64512, %ecx ## imm = 0xFC00 -; CHECK-NEXT: cmpl $32768, %ecx ## imm = 0x8000 -; CHECK-NEXT: jne LBB0_2 +; CHECK-NEXT: negw %cx +; CHECK-NEXT: jno LBB0_2 ; CHECK-NEXT: ## %bb.1: ## %bb189 ; CHECK-NEXT: ## kill: def $ax killed $ax killed $eax ; CHECK-NEXT: retl diff --git a/llvm/test/CodeGen/X86/abs.ll b/llvm/test/CodeGen/X86/abs.ll index dde877c5bb61e..bae140abdf6b1 100644 --- a/llvm/test/CodeGen/X86/abs.ll +++ b/llvm/test/CodeGen/X86/abs.ll @@ -783,8 +783,7 @@ define i32 @test_minsigned_i32(i32 %a0, i32 %a1) nounwind { ; X64-NEXT: movl %edi, %eax ; X64-NEXT: negl %eax ; X64-NEXT: cmovsl %edi, %eax -; X64-NEXT: cmpl $-2147483648, %edi # imm = 0x80000000 -; X64-NEXT: cmovel %esi, %eax +; X64-NEXT: cmovol %esi, %eax ; X64-NEXT: retq ; ; X86-LABEL: test_minsigned_i32: @@ -793,11 +792,7 @@ define i32 @test_minsigned_i32(i32 %a0, i32 %a1) nounwind { ; X86-NEXT: movl %ecx, %eax ; X86-NEXT: negl %eax ; X86-NEXT: cmovsl %ecx, %eax -; X86-NEXT: cmpl $-2147483648, %ecx # imm = 0x80000000 -; X86-NEXT: jne .LBB19_2 -; X86-NEXT: # %bb.1: -; X86-NEXT: movl {{[0-9]+}}(%esp), %eax -; X86-NEXT: .LBB19_2: +; X86-NEXT: cmovol {{[0-9]+}}(%esp), %eax ; X86-NEXT: retl %lim = icmp eq i32 %a0, -2147483648 %abs = tail call i32 @llvm.abs.i32(i32 %a0, i1 false) @@ -811,9 +806,7 @@ define i64 @test_minsigned_i64(i64 %a0, i64 %a1) nounwind { ; X64-NEXT: movq %rdi, %rax ; X64-NEXT: negq %rax ; X64-NEXT: cmovsq %rdi, %rax -; X64-NEXT: movabsq $-9223372036854775808, %rcx # imm = 0x8000000000000000 -; X64-NEXT: cmpq %rcx, %rdi -; X64-NEXT: cmoveq %rsi, %rax +; X64-NEXT: cmovoq %rsi, %rax ; X64-NEXT: retq ; ; X86-LABEL: test_minsigned_i64: diff --git a/llvm/test/CodeGen/X86/combine-sdiv.ll b/llvm/test/CodeGen/X86/combine-sdiv.ll index 49797fbefa597..5c5487815b336 100644 --- a/llvm/test/CodeGen/X86/combine-sdiv.ll +++ b/llvm/test/CodeGen/X86/combine-sdiv.ll @@ -58,8 +58,8 @@ define i32 @combine_sdiv_by_minsigned(i32 %x) { ; CHECK-LABEL: combine_sdiv_by_minsigned: ; CHECK: # %bb.0: ; CHECK-NEXT: xorl %eax, %eax -; CHECK-NEXT: cmpl $-2147483648, %edi # imm = 0x80000000 -; CHECK-NEXT: sete %al +; CHECK-NEXT: negl %edi +; CHECK-NEXT: seto %al ; CHECK-NEXT: retq %1 = sdiv i32 %x, -2147483648 ret i32 %1 diff --git a/llvm/test/CodeGen/X86/is_fpclass.ll b/llvm/test/CodeGen/X86/is_fpclass.ll index 999be0f98b6fc..532b2c09a9175 100644 --- a/llvm/test/CodeGen/X86/is_fpclass.ll +++ b/llvm/test/CodeGen/X86/is_fpclass.ll @@ -937,15 +937,16 @@ entry: define i1 @is_minus_zero_f(float %x) { ; X86-LABEL: is_minus_zero_f: ; X86: # %bb.0: # %entry -; X86-NEXT: cmpl $-2147483648, {{[0-9]+}}(%esp) # imm = 0x80000000 -; X86-NEXT: sete %al +; X86-NEXT: xorl %eax, %eax +; X86-NEXT: cmpl {{[0-9]+}}(%esp), %eax +; X86-NEXT: seto %al ; X86-NEXT: retl ; ; X64-LABEL: is_minus_zero_f: ; X64: # %bb.0: # %entry ; X64-NEXT: movd %xmm0, %eax -; X64-NEXT: cmpl $-2147483648, %eax # imm = 0x80000000 -; X64-NEXT: sete %al +; X64-NEXT: negl %eax +; X64-NEXT: seto %al ; X64-NEXT: retq entry: %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 32) ; 0x20 = "-zero" @@ -955,15 +956,16 @@ entry: define i1 @not_is_minus_zero_f(float %x) { ; X86-LABEL: not_is_minus_zero_f: ; X86: # %bb.0: # %entry -; X86-NEXT: cmpl $-2147483648, {{[0-9]+}}(%esp) # imm = 0x80000000 -; X86-NEXT: setne %al +; X86-NEXT: xorl %eax, %eax +; X86-NEXT: cmpl {{[0-9]+}}(%esp), %eax +; X86-NEXT: setno %al ; X86-NEXT: retl ; ; X64-LABEL: not_is_minus_zero_f: ; X64: # %bb.0: # %entry ; X64-NEXT: movd %xmm0, %eax -; X64-NEXT: cmpl $-2147483648, %eax # imm = 0x80000000 -; X64-NEXT: setne %al +; X64-NEXT: negl %eax +; X64-NEXT: setno %al ; X64-NEXT: retq entry: %0 = tail call i1 @llvm.is.fpclass.f32(float %x, i32 991) ; ~0x20 = ~"-zero" diff --git a/llvm/test/CodeGen/X86/lsr-overflow.ll b/llvm/test/CodeGen/X86/lsr-overflow.ll index 09c1c07ef3de0..79440c282be75 100644 --- a/llvm/test/CodeGen/X86/lsr-overflow.ll +++ b/llvm/test/CodeGen/X86/lsr-overflow.ll @@ -4,9 +4,9 @@ ; The comparison uses the pre-inc value, which could lead LSR to ; try to compute -INT64_MIN. -; CHECK: movabsq $-9223372036854775808, %rax -; CHECK: cmpq %rax, -; CHECK: sete %al +; CHECK-NOT: movabsq $-9223372036854775808, %rax +; CHECK: negq %r +; CHECK-NEXT: seto %al declare i64 @bar() diff --git a/llvm/test/CodeGen/X86/shrink-compare-pgso.ll b/llvm/test/CodeGen/X86/shrink-compare-pgso.ll index 254b8fe3fc6e3..5a15ee36c0726 100644 --- a/llvm/test/CodeGen/X86/shrink-compare-pgso.ll +++ b/llvm/test/CodeGen/X86/shrink-compare-pgso.ll @@ -265,8 +265,8 @@ if.end: define dso_local void @test_sext_i8_icmp_neg128(i8 %x) nounwind !prof !14 { ; CHECK-LABEL: test_sext_i8_icmp_neg128: ; CHECK: # %bb.0: # %entry -; CHECK-NEXT: cmpb $-128, %dil -; CHECK-NEXT: je bar # TAILCALL +; CHECK-NEXT: negb %dil +; CHECK-NEXT: jo bar # TAILCALL ; CHECK-NEXT: # %bb.1: # %if.end ; CHECK-NEXT: retq entry: diff --git a/llvm/test/CodeGen/X86/shrink-compare.ll b/llvm/test/CodeGen/X86/shrink-compare.ll index 840167ff9f4a0..1a61451c26a03 100644 --- a/llvm/test/CodeGen/X86/shrink-compare.ll +++ b/llvm/test/CodeGen/X86/shrink-compare.ll @@ -265,8 +265,8 @@ if.end: define dso_local void @test_sext_i8_icmp_neg128(i8 %x) nounwind minsize { ; CHECK-LABEL: test_sext_i8_icmp_neg128: ; CHECK: # %bb.0: # %entry -; CHECK-NEXT: cmpb $-128, %dil -; CHECK-NEXT: je bar # TAILCALL +; CHECK-NEXT: negb %dil +; CHECK-NEXT: jo bar # TAILCALL ; CHECK-NEXT: # %bb.1: # %if.end ; CHECK-NEXT: retq entry: