Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp =================================================================== --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -24463,6 +24463,37 @@ // select_cc setgt X, 0, A, 0 -> and (not (sra X, size(X)-1)), A EVT XType = N0.getValueType(); EVT AType = N2.getValueType(); + + if (!isNullConstant(N3) && isNullConstant(N2)) { + // try to swap N2 and N3. + if (!XType.isSimple() || !XType.isScalarInteger()) + return SDValue(); + ConstantSDNode *N1C = dyn_cast(N1); + if (!N1C) + return SDValue(); + // Canonicalize GE/LE comparisons to use GT/LT comparisons. + ISD::CondCode InvertedCC = ISD::getSetCCInverse(CC, XType); + if (LegalOperations && + !TLI.isCondCodeLegal(InvertedCC, XType.getSimpleVT())) + return SDValue(); + const APInt &RHSC = N1C->getAPIntValue(); + APInt C; + ISD::CondCode NewCC; + if (InvertedCC == ISD::SETLE) { + C = RHSC + 1; + NewCC = ISD::SETLT; + } else if (InvertedCC == ISD::SETGE) { + C = RHSC - 1; + NewCC = ISD::SETGT; + } else + return SDValue(); + if (LegalOperations && + (C.getBitWidth() > 64 || !TLI.isLegalICmpImmediate(C.getSExtValue()))) + return SDValue(); + return foldSelectCCToShiftAnd(DL, N0, DAG.getConstant(C, DL, XType), N3, N2, + NewCC); + } + if (!isNullConstant(N3) || !XType.bitsGE(AType)) return SDValue(); Index: llvm/test/CodeGen/AArch64/arm64-fmax.ll =================================================================== --- llvm/test/CodeGen/AArch64/arm64-fmax.ll +++ llvm/test/CodeGen/AArch64/arm64-fmax.ll @@ -59,8 +59,7 @@ define i64 @test_integer(i64 %in) { ; CHECK-LABEL: test_integer: ; CHECK: // %bb.0: -; CHECK-NEXT: cmp x0, #0 -; CHECK-NEXT: csel x0, xzr, x0, lt +; CHECK-NEXT: bic x0, x0, x0, asr #63 ; CHECK-NEXT: ret %cmp = icmp slt i64 %in, 0 %val = select i1 %cmp, i64 0, i64 %in Index: llvm/test/CodeGen/RISCV/select-to-shift-and.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/RISCV/select-to-shift-and.ll @@ -0,0 +1,97 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py + +; RUN: llc -mtriple=riscv64 -mattr=+zbb -target-abi=lp64 < %s | FileCheck %s + +define i64 @test0(i64 %a, i64 %b) { +; CHECK-LABEL: test0: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: srai a0, a0, 63 +; CHECK-NEXT: and a0, a0, a1 +; CHECK-NEXT: ret +entry: + %cmp.inv = icmp sgt i64 %a, -1 + %res = select i1 %cmp.inv, i64 0, i64 %b + ret i64 %res +} + +define i64 @test1(i64 %a, i64 %b) { +; CHECK-LABEL: test1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: srai a0, a0, 63 +; CHECK-NEXT: and a0, a0, a1 +; CHECK-NEXT: ret +entry: + %cmp.inv = icmp slt i64 %a, 0 + %res = select i1 %cmp.inv, i64 %b, i64 0 + ret i64 %res +} + +define i64 @test2(i64 %a, i64 %b) { +; CHECK-LABEL: test2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: srai a0, a0, 63 +; CHECK-NEXT: andn a0, a1, a0 +; CHECK-NEXT: ret +entry: + %cmp.inv = icmp sgt i64 %a, -1 + %res = select i1 %cmp.inv, i64 %b, i64 0 + ret i64 %res +} + +define i64 @test3(i64 %a, i64 %b) { +; CHECK-LABEL: test3: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: srai a0, a0, 63 +; CHECK-NEXT: andn a0, a1, a0 +; CHECK-NEXT: ret +entry: + %cmp.inv = icmp slt i64 %a, 0 + %res = select i1 %cmp.inv, i64 0, i64 %b + ret i64 %res +} + +define i64 @test4(i64 %x) { +; CHECK-LABEL: test4: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: min a0, a0, zero +; CHECK-NEXT: ret +entry: + %cmp.inv = icmp sgt i64 %x, 0 + %res = select i1 %cmp.inv, i64 0, i64 %x + ret i64 %res +} + +define i64 @test5(i64 %x) { +; CHECK-LABEL: test5: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: srai a1, a0, 63 +; CHECK-NEXT: and a0, a1, a0 +; CHECK-NEXT: ret +entry: + %cmp.inv = icmp slt i64 %x, 1 + %res = select i1 %cmp.inv, i64 %x, i64 0 + ret i64 %res +} + +define i64 @test6(i64 %x) { +; CHECK-LABEL: test6: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: max a0, a0, zero +; CHECK-NEXT: ret +entry: + %cmp.inv = icmp sgt i64 %x, 0 + %res = select i1 %cmp.inv, i64 %x, i64 0 + ret i64 %res +} + +define i64 @test7(i64 %x) { +; CHECK-LABEL: test7: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: srai a1, a0, 63 +; CHECK-NEXT: andn a0, a0, a1 +; CHECK-NEXT: ret +entry: + %cmp.inv = icmp slt i64 %x, 1 + %res = select i1 %cmp.inv, i64 0, i64 %x + ret i64 %res +}