diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -48489,6 +48489,31 @@ if (SDValue R = combineLogicBlendIntoPBLENDV(N, DAG, Subtarget)) return R; + // (0 - SetCC) | C -> (zext (not SetCC)) * (C + 1) - 1 if we can get a LEA out of it. + if ((VT == MVT::i32 || VT == MVT::i64) && + N0.getOpcode() == ISD::SUB && N0.hasOneUse() && + isNullConstant(N0.getOperand(0))) { + SDValue Cond = N0.getOperand(1); + if (Cond.getOpcode() == ISD::ZERO_EXTEND && Cond.hasOneUse()) + Cond = Cond.getOperand(0); + + if (Cond.getOpcode() == X86ISD::SETCC && Cond.hasOneUse()) { + if (auto *CN = dyn_cast(N1)) { + unsigned Val = CN->getZExtValue(); + if (Val == 1 || Val == 2 || Val == 3 || Val == 4 || Val == 7 || Val == 8) { + X86::CondCode CCode = (X86::CondCode)Cond.getConstantOperandVal(0); + CCode = X86::GetOppositeBranchCondition(CCode); + SDValue NotCond = getSETCC(CCode, Cond.getOperand(1), SDLoc(Cond), DAG); + + SDValue R = DAG.getZExtOrTrunc(NotCond, dl, VT); + R = DAG.getNode(ISD::MUL, dl, VT, R, DAG.getConstant(Val + 1, dl, VT)); + R = DAG.getNode(ISD::SUB, dl, VT, R, DAG.getConstant(1, dl, VT)); + return R; + } + } + } + } + // Combine OR(X,KSHIFTL(Y,Elts/2)) -> CONCAT_VECTORS(X,Y) == KUNPCK(X,Y). // Combine OR(KSHIFTL(X,Elts/2),Y) -> CONCAT_VECTORS(Y,X) == KUNPCK(Y,X). // iff the upper elements of the non-shifted arg are zero. diff --git a/llvm/test/CodeGen/X86/or-lea.ll b/llvm/test/CodeGen/X86/or-lea.ll --- a/llvm/test/CodeGen/X86/or-lea.ll +++ b/llvm/test/CodeGen/X86/or-lea.ll @@ -504,18 +504,16 @@ ; X86: # %bb.0: ; X86-NEXT: xorl %eax, %eax ; X86-NEXT: cmpl $43, {{[0-9]+}}(%esp) -; X86-NEXT: setge %al -; X86-NEXT: negl %eax -; X86-NEXT: orl $1, %eax +; X86-NEXT: setl %al +; X86-NEXT: leal -1(%eax,%eax), %eax ; X86-NEXT: retl ; ; X64-LABEL: or_sext1: ; X64: # %bb.0: ; X64-NEXT: xorl %eax, %eax ; X64-NEXT: cmpl $43, %edi -; X64-NEXT: setge %al -; X64-NEXT: negl %eax -; X64-NEXT: orl $1, %eax +; X64-NEXT: setl %al +; X64-NEXT: leal -1(%rax,%rax), %eax ; X64-NEXT: retq %cmp = icmp sgt i32 %x, 42 %sext = sext i1 %cmp to i32 @@ -541,9 +539,8 @@ ; X64: # %bb.0: ; X64-NEXT: xorl %eax, %eax ; X64-NEXT: cmpq $43, %rdi -; X64-NEXT: setge %al -; X64-NEXT: negq %rax -; X64-NEXT: orq $1, %rax +; X64-NEXT: setl %al +; X64-NEXT: leaq -1(%rax,%rax), %rax ; X64-NEXT: retq %cmp = icmp sgt i64 %x, 42 %sext = sext i1 %cmp to i64 @@ -556,18 +553,16 @@ ; X86: # %bb.0: ; X86-NEXT: xorl %eax, %eax ; X86-NEXT: cmpl $43, {{[0-9]+}}(%esp) -; X86-NEXT: setge %al -; X86-NEXT: negl %eax -; X86-NEXT: orl $2, %eax +; X86-NEXT: setl %al +; X86-NEXT: leal -1(%eax,%eax,2), %eax ; X86-NEXT: retl ; ; X64-LABEL: or_sext2: ; X64: # %bb.0: ; X64-NEXT: xorl %eax, %eax ; X64-NEXT: cmpl $43, %edi -; X64-NEXT: setge %al -; X64-NEXT: negl %eax -; X64-NEXT: orl $2, %eax +; X64-NEXT: setl %al +; X64-NEXT: leal -1(%rax,%rax,2), %eax ; X64-NEXT: retq %cmp = icmp sgt i32 %x, 42 %sext = sext i1 %cmp to i32 @@ -593,9 +588,8 @@ ; X64: # %bb.0: ; X64-NEXT: xorl %eax, %eax ; X64-NEXT: cmpq $43, %rdi -; X64-NEXT: setge %al -; X64-NEXT: negq %rax -; X64-NEXT: orq $2, %rax +; X64-NEXT: setl %al +; X64-NEXT: leaq -1(%rax,%rax,2), %rax ; X64-NEXT: retq %cmp = icmp sgt i64 %x, 42 %sext = sext i1 %cmp to i64 @@ -608,18 +602,16 @@ ; X86: # %bb.0: ; X86-NEXT: xorl %eax, %eax ; X86-NEXT: cmpl $43, {{[0-9]+}}(%esp) -; X86-NEXT: setge %al -; X86-NEXT: negl %eax -; X86-NEXT: orl $3, %eax +; X86-NEXT: setl %al +; X86-NEXT: leal -1(,%eax,4), %eax ; X86-NEXT: retl ; ; X64-LABEL: or_sext3: ; X64: # %bb.0: ; X64-NEXT: xorl %eax, %eax ; X64-NEXT: cmpl $43, %edi -; X64-NEXT: setge %al -; X64-NEXT: negl %eax -; X64-NEXT: orl $3, %eax +; X64-NEXT: setl %al +; X64-NEXT: leal -1(,%rax,4), %eax ; X64-NEXT: retq %cmp = icmp sgt i32 %x, 42 %sext = sext i1 %cmp to i32 @@ -645,9 +637,8 @@ ; X64: # %bb.0: ; X64-NEXT: xorl %eax, %eax ; X64-NEXT: cmpq $43, %rdi -; X64-NEXT: setge %al -; X64-NEXT: negq %rax -; X64-NEXT: orq $3, %rax +; X64-NEXT: setl %al +; X64-NEXT: leaq -1(,%rax,4), %rax ; X64-NEXT: retq %cmp = icmp sgt i64 %x, 42 %sext = sext i1 %cmp to i64 @@ -660,18 +651,16 @@ ; X86: # %bb.0: ; X86-NEXT: xorl %eax, %eax ; X86-NEXT: cmpl $43, {{[0-9]+}}(%esp) -; X86-NEXT: setge %al -; X86-NEXT: negl %eax -; X86-NEXT: orl $4, %eax +; X86-NEXT: setl %al +; X86-NEXT: leal -1(%eax,%eax,4), %eax ; X86-NEXT: retl ; ; X64-LABEL: or_sext4: ; X64: # %bb.0: ; X64-NEXT: xorl %eax, %eax ; X64-NEXT: cmpl $43, %edi -; X64-NEXT: setge %al -; X64-NEXT: negl %eax -; X64-NEXT: orl $4, %eax +; X64-NEXT: setl %al +; X64-NEXT: leal -1(%rax,%rax,4), %eax ; X64-NEXT: retq %cmp = icmp sgt i32 %x, 42 %sext = sext i1 %cmp to i32 @@ -697,9 +686,8 @@ ; X64: # %bb.0: ; X64-NEXT: xorl %eax, %eax ; X64-NEXT: cmpq $43, %rdi -; X64-NEXT: setge %al -; X64-NEXT: negq %rax -; X64-NEXT: orq $4, %rax +; X64-NEXT: setl %al +; X64-NEXT: leaq -1(%rax,%rax,4), %rax ; X64-NEXT: retq %cmp = icmp sgt i64 %x, 42 %sext = sext i1 %cmp to i64 @@ -712,18 +700,16 @@ ; X86: # %bb.0: ; X86-NEXT: xorl %eax, %eax ; X86-NEXT: cmpl $43, {{[0-9]+}}(%esp) -; X86-NEXT: setge %al -; X86-NEXT: negl %eax -; X86-NEXT: orl $7, %eax +; X86-NEXT: setl %al +; X86-NEXT: leal -1(,%eax,8), %eax ; X86-NEXT: retl ; ; X64-LABEL: or_sext7: ; X64: # %bb.0: ; X64-NEXT: xorl %eax, %eax ; X64-NEXT: cmpl $43, %edi -; X64-NEXT: setge %al -; X64-NEXT: negl %eax -; X64-NEXT: orl $7, %eax +; X64-NEXT: setl %al +; X64-NEXT: leal -1(,%rax,8), %eax ; X64-NEXT: retq %cmp = icmp sgt i32 %x, 42 %sext = sext i1 %cmp to i32 @@ -749,9 +735,8 @@ ; X64: # %bb.0: ; X64-NEXT: xorl %eax, %eax ; X64-NEXT: cmpq $43, %rdi -; X64-NEXT: setge %al -; X64-NEXT: negq %rax -; X64-NEXT: orq $7, %rax +; X64-NEXT: setl %al +; X64-NEXT: leaq -1(,%rax,8), %rax ; X64-NEXT: retq %cmp = icmp sgt i64 %x, 42 %sext = sext i1 %cmp to i64 @@ -764,18 +749,16 @@ ; X86: # %bb.0: ; X86-NEXT: xorl %eax, %eax ; X86-NEXT: cmpl $43, {{[0-9]+}}(%esp) -; X86-NEXT: setge %al -; X86-NEXT: negl %eax -; X86-NEXT: orl $8, %eax +; X86-NEXT: setl %al +; X86-NEXT: leal -1(%eax,%eax,8), %eax ; X86-NEXT: retl ; ; X64-LABEL: or_sext8: ; X64: # %bb.0: ; X64-NEXT: xorl %eax, %eax ; X64-NEXT: cmpl $43, %edi -; X64-NEXT: setge %al -; X64-NEXT: negl %eax -; X64-NEXT: orl $8, %eax +; X64-NEXT: setl %al +; X64-NEXT: leal -1(%rax,%rax,8), %eax ; X64-NEXT: retq %cmp = icmp sgt i32 %x, 42 %sext = sext i1 %cmp to i32 @@ -801,9 +784,8 @@ ; X64: # %bb.0: ; X64-NEXT: xorl %eax, %eax ; X64-NEXT: cmpq $43, %rdi -; X64-NEXT: setge %al -; X64-NEXT: negq %rax -; X64-NEXT: orq $8, %rax +; X64-NEXT: setl %al +; X64-NEXT: leaq -1(%rax,%rax,8), %rax ; X64-NEXT: retq %cmp = icmp sgt i64 %x, 42 %sext = sext i1 %cmp to i64