From e0e960923ff3666c090cd4e4a3509377f1ecf167 Mon Sep 17 00:00:00 2001 From: Vitaly Buka Date: Mon, 15 Aug 2022 14:59:50 -0700 Subject: [PATCH] [AArch64] Fix signed integer overflow in CSINC case Followup to D131815, which overlflows on different values. --- llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | 20 ++++++++++--------- llvm/test/CodeGen/AArch64/arm64-csel.ll | 26 +++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index 92e6430..4481138 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -8235,15 +8235,17 @@ SDValue AArch64TargetLowering::LowerSELECT_CC(ISD::CondCode CC, SDValue LHS, Swap = true; } } - // 64-bit check whether we can use CSINC. To avoid signed integer - // overflow the condition ignores wrap around, which is already - // handled by CSINV above. - } else if (1 == - std::max(TrueVal, FalseVal) - std::min(TrueVal, FalseVal)) { - Opcode = AArch64ISD::CSINC; - - if (TrueVal > FalseVal) { - Swap = true; + } else { + // 64-bit check whether we can use CSINC. + const uint64_t TrueVal64 = TrueVal; + const uint64_t FalseVal64 = FalseVal; + + if ((TrueVal64 == FalseVal64 + 1) || (TrueVal64 + 1 == FalseVal64)) { + Opcode = AArch64ISD::CSINC; + + if (TrueVal > FalseVal) { + Swap = true; + } } } diff --git a/llvm/test/CodeGen/AArch64/arm64-csel.ll b/llvm/test/CodeGen/AArch64/arm64-csel.ll index cbb367d..e04b42d 100644 --- a/llvm/test/CodeGen/AArch64/arm64-csel.ll +++ b/llvm/test/CodeGen/AArch64/arm64-csel.ll @@ -292,6 +292,32 @@ entry: ret i64 %. } +; Regression test for FalseVal - TrueVal overflow +define i64 @foo18_overflow3(i1 %cmp) nounwind readnone optsize ssp { +; CHECK-LABEL: foo18_overflow3: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: mov x8, #-9223372036854775808 +; CHECK-NEXT: tst w0, #0x1 +; CHECK-NEXT: csel x0, x8, xzr, ne +; CHECK-NEXT: ret +entry: + %. = select i1 %cmp, i64 -9223372036854775808, i64 0 + ret i64 %. +} + +; Regression test for TrueVal - FalseVal overflow +define i64 @foo18_overflow4(i1 %cmp) nounwind readnone optsize ssp { +; CHECK-LABEL: foo18_overflow4: +; CHECK: // %bb.0: // %entry +; CHECK-NEXT: mov x8, #-9223372036854775808 +; CHECK-NEXT: tst w0, #0x1 +; CHECK-NEXT: csel x0, xzr, x8, ne +; CHECK-NEXT: ret +entry: + %. = select i1 %cmp, i64 0, i64 -9223372036854775808 + ret i64 %. +} + define i64 @foo19(i64 %a, i64 %b, i64 %c) { ; CHECK-LABEL: foo19: ; CHECK: // %bb.0: // %entry -- 2.7.4