Index: lib/Target/AArch64/AArch64ISelLowering.cpp =================================================================== --- lib/Target/AArch64/AArch64ISelLowering.cpp +++ lib/Target/AArch64/AArch64ISelLowering.cpp @@ -3995,8 +3995,14 @@ // instead of a CSEL in that case. if (TrueVal == ~FalseVal) { Opcode = AArch64ISD::CSINV; + ConstantSDNode *RHSVal = dyn_cast(RHS); + if (CTVal == RHSVal && changeIntCCToAArch64CC(CC) == AArch64CC::EQ) + TVal = LHS; } else if (TrueVal == -FalseVal) { Opcode = AArch64ISD::CSNEG; + ConstantSDNode *RHSVal = dyn_cast(RHS); + if (CTVal == RHSVal && changeIntCCToAArch64CC(CC) == AArch64CC::EQ) + TVal = LHS; } else if (TVal.getValueType() == MVT::i32) { // If our operands are only 32-bit wide, make sure we use 32-bit // arithmetic for the check whether we can use CSINC. This ensures that Index: test/CodeGen/AArch64/arm64-csel.ll =================================================================== --- test/CodeGen/AArch64/arm64-csel.ll +++ test/CodeGen/AArch64/arm64-csel.ll @@ -228,3 +228,69 @@ %inc.c = add i64 %inc, %c ret i64 %inc.c } + +define i32 @foo20(i32 %x) { +entry: +; CHECK-LABEL: foo20: +; CHECK: cmp w[[REG:[0-9]+]], #1 +; CHECK-NOT: orr w{{[0-9]+}}, wzr, #0x1 +; CHECK: cneg w0, w[[REG]], ne + %cmp = icmp eq i32 %x, 1 + %res = select i1 %cmp, i32 1, i32 -1 + ret i32 %res +} + +define i64 @foo21(i64 %x) { +entry: +; CHECK-LABEL: foo21: +; CHECK: cmp x[[REG:[0-9]+]], #1 +; CHECK-NOT: orr w{{[0-9]+}}, wzr, #0x1 +; CHECK: cneg x0, x[[REG]], ne + %cmp = icmp eq i64 %x, 1 + %res = select i1 %cmp, i64 1, i64 -1 + ret i64 %res +} + +define i32 @foo22(i32 %x) { +entry: +; CHECK-LABEL: foo22: +; CHECK: cmp w[[REG:[0-9]+]], #3 +; CHECK-NOT: orr w{{[0-9]+}}, wzr, #0x3 +; CHECK: cneg w0, w[[REG]], ne + %cmp = icmp eq i32 %x, 3 + %res = select i1 %cmp, i32 3, i32 -3 + ret i32 %res +} + +define i64 @foo23(i64 %x) { +entry: +; CHECK-LABEL: foo23: +; CHECK: cmp x[[REG:[0-9]+]], #3 +; CHECK-NOT: orr w{{[0-9]+}}, wzr, #0x3 +; CHECK: cneg x0, x[[REG]], ne + %cmp = icmp eq i64 %x, 3 + %res = select i1 %cmp, i64 3, i64 -3 + ret i64 %res +} + +define i32 @foo24(i32 %x) { +entry: +; CHECK-LABEL: foo24: +; CHECK: cmp w[[REG:[0-9]+]], #4 +; CHECK-NOT: orr w{{[0-9]+}}, wzr, #0x4 +; CHECK: cinv w0, w[[REG]], ne + %cmp = icmp eq i32 %x, 4 + %res = select i1 %cmp, i32 4, i32 -5 + ret i32 %res +} + +define i64 @foo25(i64 %x) { +entry: +; CHECK-LABEL: foo25: +; CHECK: cmp x[[REG:[0-9]+]], #4 +; CHECK-NOT: orr w{{[0-9]+}}, wzr, #0x4 +; CHECK: cinv x0, x[[REG]], ne + %cmp = icmp eq i64 %x, 4 + %res = select i1 %cmp, i64 4, i64 -5 + ret i64 %res +}