Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp =================================================================== --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -10872,6 +10872,50 @@ } } + // If we have a chain of two selects, which share true/false value and both + // are controlled from the two setcc nodes which cannot produce the same + // value, we can fold away N. + // select (setcc X), Y, (select (setcc X), Z, Y) -> select (setcc X), Z, Y + auto IsSelect = [](SDValue Op) { + return Op->getOpcode() == ISD::SELECT; + }; + if ((IsSelect(N1) || IsSelect(N2)) && (N1.getOpcode() != N2.getOpcode())) { + auto AreSame = [](SDValue Op0, SDValue Op1) { + if (Op0 == Op1) + return true; + auto *C0 = dyn_cast(Op0); + auto *C1 = dyn_cast(Op1); + return C0 && C1 && + APInt::isSameValue(C0->getAPIntValue(), C1->getAPIntValue()); + }; + + SDValue OtherSelect; + bool SelectsShareOp = false; + if (IsSelect(N1)) { + OtherSelect = N1; + SelectsShareOp = AreSame(OtherSelect.getOperand(1), N2); + } else { + OtherSelect = N2; + SelectsShareOp = AreSame(OtherSelect.getOperand(2), N1); + } + + auto EqualToConstant = [](SDValue SetCC) { + if (SetCC.getOpcode() != ISD::SETCC) + return false; + ISD::CondCode CC = cast(SetCC.getOperand(2))->get(); + return CC == ISD::SETEQ && isa(SetCC.getOperand(1)); + }; + + SDValue SetCC0 = N0; + SDValue SetCC1 = OtherSelect.getOperand(0); + if (SelectsShareOp && + EqualToConstant(SetCC0) && EqualToConstant(SetCC1) && + SetCC0->getOperand(0) == SetCC1->getOperand(0) && + SetCC0->getOperand(1) != SetCC1->getOperand(1)) { + return OtherSelect; + } + } + if (TLI.isOperationLegal(ISD::SELECT_CC, VT) || (!LegalOperations && TLI.isOperationLegalOrCustom(ISD::SELECT_CC, VT))) { Index: llvm/test/CodeGen/RISCV/fpclamptosat_vec.ll =================================================================== --- llvm/test/CodeGen/RISCV/fpclamptosat_vec.ll +++ llvm/test/CodeGen/RISCV/fpclamptosat_vec.ll @@ -5572,11 +5572,7 @@ ; CHECK-NOV-NEXT: mv s1, a1 ; CHECK-NOV-NEXT: fmv.d fa0, fs0 ; CHECK-NOV-NEXT: call __fixunsdfti@plt -; CHECK-NOV-NEXT: snez a2, a1 -; CHECK-NOV-NEXT: addi a2, a2, -1 -; CHECK-NOV-NEXT: and a0, a2, a0 -; CHECK-NOV-NEXT: addi a1, a1, -1 -; CHECK-NOV-NEXT: seqz a1, a1 +; CHECK-NOV-NEXT: snez a1, a1 ; CHECK-NOV-NEXT: addi a1, a1, -1 ; CHECK-NOV-NEXT: and a0, a1, a0 ; CHECK-NOV-NEXT: snez a1, s1 @@ -5627,11 +5623,7 @@ ; CHECK-V-NEXT: seqz a3, s1 ; CHECK-V-NEXT: addi a3, a3, -1 ; CHECK-V-NEXT: and a2, a3, a2 -; CHECK-V-NEXT: snez a3, a1 -; CHECK-V-NEXT: addi a3, a3, -1 -; CHECK-V-NEXT: and a0, a3, a0 -; CHECK-V-NEXT: addi a1, a1, -1 -; CHECK-V-NEXT: seqz a1, a1 +; CHECK-V-NEXT: snez a1, a1 ; CHECK-V-NEXT: addi a1, a1, -1 ; CHECK-V-NEXT: and a0, a1, a0 ; CHECK-V-NEXT: sd a0, 24(sp) @@ -6062,11 +6054,7 @@ ; CHECK-NOV-NEXT: mv s1, a1 ; CHECK-NOV-NEXT: fmv.s fa0, fs0 ; CHECK-NOV-NEXT: call __fixunssfti@plt -; CHECK-NOV-NEXT: snez a2, a1 -; CHECK-NOV-NEXT: addi a2, a2, -1 -; CHECK-NOV-NEXT: and a0, a2, a0 -; CHECK-NOV-NEXT: addi a1, a1, -1 -; CHECK-NOV-NEXT: seqz a1, a1 +; CHECK-NOV-NEXT: snez a1, a1 ; CHECK-NOV-NEXT: addi a1, a1, -1 ; CHECK-NOV-NEXT: and a0, a1, a0 ; CHECK-NOV-NEXT: snez a1, s1 @@ -6117,11 +6105,7 @@ ; CHECK-V-NEXT: seqz a3, s1 ; CHECK-V-NEXT: addi a3, a3, -1 ; CHECK-V-NEXT: and a2, a3, a2 -; CHECK-V-NEXT: snez a3, a1 -; CHECK-V-NEXT: addi a3, a3, -1 -; CHECK-V-NEXT: and a0, a3, a0 -; CHECK-V-NEXT: addi a1, a1, -1 -; CHECK-V-NEXT: seqz a1, a1 +; CHECK-V-NEXT: snez a1, a1 ; CHECK-V-NEXT: addi a1, a1, -1 ; CHECK-V-NEXT: and a0, a1, a0 ; CHECK-V-NEXT: sd a0, 24(sp) @@ -6547,11 +6531,7 @@ ; CHECK-NOV-NEXT: mv a0, s0 ; CHECK-NOV-NEXT: call __extendhfsf2@plt ; CHECK-NOV-NEXT: call __fixunssfti@plt -; CHECK-NOV-NEXT: snez a2, a1 -; CHECK-NOV-NEXT: addi a2, a2, -1 -; CHECK-NOV-NEXT: and a0, a2, a0 -; CHECK-NOV-NEXT: addi a1, a1, -1 -; CHECK-NOV-NEXT: seqz a1, a1 +; CHECK-NOV-NEXT: snez a1, a1 ; CHECK-NOV-NEXT: addi a1, a1, -1 ; CHECK-NOV-NEXT: and a0, a1, a0 ; CHECK-NOV-NEXT: snez a1, s2 @@ -6580,8 +6560,7 @@ ; CHECK-V-NEXT: .cfi_offset s0, -16 ; CHECK-V-NEXT: .cfi_offset s1, -24 ; CHECK-V-NEXT: .cfi_offset s2, -32 -; CHECK-V-NEXT: mv s0, a0 -; CHECK-V-NEXT: mv a0, a1 +; CHECK-V-NEXT: mv s0, a1 ; CHECK-V-NEXT: call __extendhfsf2@plt ; CHECK-V-NEXT: call __fixunssfti@plt ; CHECK-V-NEXT: mv s1, a0 @@ -6599,17 +6578,13 @@ ; CHECK-V-NEXT: snez a1, s2 ; CHECK-V-NEXT: addi a1, a1, -1 ; CHECK-V-NEXT: and a1, a1, s1 -; CHECK-V-NEXT: addi s2, s2, -1 -; CHECK-V-NEXT: seqz a2, s2 -; CHECK-V-NEXT: addi a2, a2, -1 -; CHECK-V-NEXT: and a1, a2, a1 -; CHECK-V-NEXT: sd a1, 8(sp) -; CHECK-V-NEXT: sd a0, 0(sp) -; CHECK-V-NEXT: addi a0, sp, 8 -; CHECK-V-NEXT: vsetivli zero, 1, e64, m1, ta, ma -; CHECK-V-NEXT: vle64.v v9, (a0) +; CHECK-V-NEXT: sd a1, 0(sp) +; CHECK-V-NEXT: sd a0, 8(sp) ; CHECK-V-NEXT: mv a0, sp +; CHECK-V-NEXT: vsetivli zero, 1, e64, m1, ta, ma ; CHECK-V-NEXT: vle64.v v8, (a0) +; CHECK-V-NEXT: addi a0, sp, 8 +; CHECK-V-NEXT: vle64.v v9, (a0) ; CHECK-V-NEXT: vsetivli zero, 2, e64, m1, ta, ma ; CHECK-V-NEXT: vslideup.vi v8, v9, 1 ; CHECK-V-NEXT: ld ra, 40(sp) # 8-byte Folded Reload Index: llvm/test/CodeGen/WebAssembly/fpclamptosat.ll =================================================================== --- llvm/test/CodeGen/WebAssembly/fpclamptosat.ll +++ llvm/test/CodeGen/WebAssembly/fpclamptosat.ll @@ -589,16 +589,11 @@ ; CHECK-NEXT: i32.const 16 ; CHECK-NEXT: i32.add ; CHECK-NEXT: global.set __stack_pointer -; CHECK-NEXT: i64.const 0 ; CHECK-NEXT: local.get 3 ; CHECK-NEXT: i64.const 0 ; CHECK-NEXT: local.get 2 ; CHECK-NEXT: i64.eqz ; CHECK-NEXT: i64.select -; CHECK-NEXT: local.get 2 -; CHECK-NEXT: i64.const 1 -; CHECK-NEXT: i64.eq -; CHECK-NEXT: i64.select ; CHECK-NEXT: # fallthrough-return entry: %conv = fptoui double %x to i128 @@ -1539,16 +1534,11 @@ ; CHECK-NEXT: i32.const 16 ; CHECK-NEXT: i32.add ; CHECK-NEXT: global.set __stack_pointer -; CHECK-NEXT: i64.const 0 ; CHECK-NEXT: local.get 3 ; CHECK-NEXT: i64.const 0 ; CHECK-NEXT: local.get 2 ; CHECK-NEXT: i64.eqz ; CHECK-NEXT: i64.select -; CHECK-NEXT: local.get 2 -; CHECK-NEXT: i64.const 1 -; CHECK-NEXT: i64.eq -; CHECK-NEXT: i64.select ; CHECK-NEXT: # fallthrough-return entry: %conv = fptoui double %x to i128 @@ -1657,16 +1647,11 @@ ; CHECK-NEXT: i32.const 16 ; CHECK-NEXT: i32.add ; CHECK-NEXT: global.set __stack_pointer -; CHECK-NEXT: i64.const 0 ; CHECK-NEXT: local.get 3 ; CHECK-NEXT: i64.const 0 ; CHECK-NEXT: local.get 2 ; CHECK-NEXT: i64.eqz ; CHECK-NEXT: i64.select -; CHECK-NEXT: local.get 2 -; CHECK-NEXT: i64.const 1 -; CHECK-NEXT: i64.eq -; CHECK-NEXT: i64.select ; CHECK-NEXT: # fallthrough-return entry: %conv = fptoui float %x to i128 @@ -1779,16 +1764,11 @@ ; CHECK-NEXT: i32.const 16 ; CHECK-NEXT: i32.add ; CHECK-NEXT: global.set __stack_pointer -; CHECK-NEXT: i64.const 0 ; CHECK-NEXT: local.get 3 ; CHECK-NEXT: i64.const 0 ; CHECK-NEXT: local.get 2 ; CHECK-NEXT: i64.eqz ; CHECK-NEXT: i64.select -; CHECK-NEXT: local.get 2 -; CHECK-NEXT: i64.const 1 -; CHECK-NEXT: i64.eq -; CHECK-NEXT: i64.select ; CHECK-NEXT: # fallthrough-return entry: %conv = fptoui half %x to i128 Index: llvm/test/CodeGen/WebAssembly/fpclamptosat_vec.ll =================================================================== --- llvm/test/CodeGen/WebAssembly/fpclamptosat_vec.ll +++ llvm/test/CodeGen/WebAssembly/fpclamptosat_vec.ll @@ -2309,27 +2309,17 @@ ; CHECK-NEXT: i32.const 32 ; CHECK-NEXT: i32.add ; CHECK-NEXT: global.set __stack_pointer -; CHECK-NEXT: i64.const 0 ; CHECK-NEXT: local.get 5 ; CHECK-NEXT: i64.const 0 ; CHECK-NEXT: local.get 4 ; CHECK-NEXT: i64.eqz ; CHECK-NEXT: i64.select -; CHECK-NEXT: local.get 4 -; CHECK-NEXT: i64.const 1 -; CHECK-NEXT: i64.eq -; CHECK-NEXT: i64.select ; CHECK-NEXT: i64x2.splat -; CHECK-NEXT: i64.const 0 ; CHECK-NEXT: local.get 3 ; CHECK-NEXT: i64.const 0 ; CHECK-NEXT: local.get 2 ; CHECK-NEXT: i64.eqz ; CHECK-NEXT: i64.select -; CHECK-NEXT: local.get 2 -; CHECK-NEXT: i64.const 1 -; CHECK-NEXT: i64.eq -; CHECK-NEXT: i64.select ; CHECK-NEXT: i64x2.replace_lane 1 ; CHECK-NEXT: # fallthrough-return entry: @@ -2611,27 +2601,17 @@ ; CHECK-NEXT: i32.const 32 ; CHECK-NEXT: i32.add ; CHECK-NEXT: global.set __stack_pointer -; CHECK-NEXT: i64.const 0 ; CHECK-NEXT: local.get 5 ; CHECK-NEXT: i64.const 0 ; CHECK-NEXT: local.get 4 ; CHECK-NEXT: i64.eqz ; CHECK-NEXT: i64.select -; CHECK-NEXT: local.get 4 -; CHECK-NEXT: i64.const 1 -; CHECK-NEXT: i64.eq -; CHECK-NEXT: i64.select ; CHECK-NEXT: i64x2.splat -; CHECK-NEXT: i64.const 0 ; CHECK-NEXT: local.get 3 ; CHECK-NEXT: i64.const 0 ; CHECK-NEXT: local.get 2 ; CHECK-NEXT: i64.eqz ; CHECK-NEXT: i64.select -; CHECK-NEXT: local.get 2 -; CHECK-NEXT: i64.const 1 -; CHECK-NEXT: i64.eq -; CHECK-NEXT: i64.select ; CHECK-NEXT: i64x2.replace_lane 1 ; CHECK-NEXT: # fallthrough-return entry: @@ -2917,27 +2897,17 @@ ; CHECK-NEXT: i32.const 32 ; CHECK-NEXT: i32.add ; CHECK-NEXT: global.set __stack_pointer -; CHECK-NEXT: i64.const 0 ; CHECK-NEXT: local.get 6 ; CHECK-NEXT: i64.const 0 ; CHECK-NEXT: local.get 5 ; CHECK-NEXT: i64.eqz ; CHECK-NEXT: i64.select -; CHECK-NEXT: local.get 5 -; CHECK-NEXT: i64.const 1 -; CHECK-NEXT: i64.eq -; CHECK-NEXT: i64.select ; CHECK-NEXT: i64x2.splat -; CHECK-NEXT: i64.const 0 ; CHECK-NEXT: local.get 4 ; CHECK-NEXT: i64.const 0 ; CHECK-NEXT: local.get 3 ; CHECK-NEXT: i64.eqz ; CHECK-NEXT: i64.select -; CHECK-NEXT: local.get 3 -; CHECK-NEXT: i64.const 1 -; CHECK-NEXT: i64.eq -; CHECK-NEXT: i64.select ; CHECK-NEXT: i64x2.replace_lane 1 ; CHECK-NEXT: # fallthrough-return entry: Index: llvm/test/CodeGen/X86/fpclamptosat_vec.ll =================================================================== --- llvm/test/CodeGen/X86/fpclamptosat_vec.ll +++ llvm/test/CodeGen/X86/fpclamptosat_vec.ll @@ -2766,8 +2766,6 @@ ; CHECK-NEXT: cmoveq %rcx, %rax ; CHECK-NEXT: testq %r14, %r14 ; CHECK-NEXT: cmovneq %rcx, %rbx -; CHECK-NEXT: cmpq $1, %r14 -; CHECK-NEXT: cmoveq %rcx, %rbx ; CHECK-NEXT: movq %rbx, %xmm0 ; CHECK-NEXT: movq %rax, %xmm1 ; CHECK-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] @@ -2930,8 +2928,6 @@ ; CHECK-NEXT: cmoveq %rcx, %rax ; CHECK-NEXT: testq %r14, %r14 ; CHECK-NEXT: cmovneq %rcx, %rbx -; CHECK-NEXT: cmpq $1, %r14 -; CHECK-NEXT: cmoveq %rcx, %rbx ; CHECK-NEXT: movq %rbx, %xmm0 ; CHECK-NEXT: movq %rax, %xmm1 ; CHECK-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0] @@ -3095,8 +3091,6 @@ ; CHECK-NEXT: cmoveq %rcx, %rax ; CHECK-NEXT: testq %r14, %r14 ; CHECK-NEXT: cmovneq %rcx, %rbx -; CHECK-NEXT: cmpq $1, %r14 -; CHECK-NEXT: cmoveq %rcx, %rbx ; CHECK-NEXT: movq %rbx, %xmm0 ; CHECK-NEXT: movq %rax, %xmm1 ; CHECK-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]