From 183bbad1d78a4bf445ec4db1ce01673f6a7feb37 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Sun, 21 Feb 2021 14:48:27 -0800 Subject: [PATCH] [KnownBits][RISCV] Improve known bits for srem. The result must be less than or equal to the LHS side, so any leading zeros in the left hand side must also exist in the result. This is stronger than the previous behavior where we only considered the sign bit being 0. The affected test case used the sign bit being known 0 to change a sign extend to a zero extend pre type legalization. After type legalization the types were promoted to i64, but we no longer knew bit 31 was zero. This shifts are are the equivalent of an AND with 0xffffffff or zext_inreg X, i32. This patch allows us to see that bit 31 is zero and remove the shifts. Reviewed By: RKSimon Differential Revision: https://reviews.llvm.org/D97124 --- llvm/lib/Support/KnownBits.cpp | 7 ++++--- llvm/test/CodeGen/RISCV/rv64m-exhaustive-w-insts.ll | 2 -- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/llvm/lib/Support/KnownBits.cpp b/llvm/lib/Support/KnownBits.cpp index 3623a54..6acd841 100644 --- a/llvm/lib/Support/KnownBits.cpp +++ b/llvm/lib/Support/KnownBits.cpp @@ -474,9 +474,10 @@ KnownBits KnownBits::srem(const KnownBits &LHS, const KnownBits &RHS) { } // The sign bit is the LHS's sign bit, except when the result of the - // remainder is zero. If it's known zero, our sign bit is also zero. - if (LHS.isNonNegative()) - Known.makeNonNegative(); + // remainder is zero. The magnitude of the result should be less than or + // equal to the magnitude of the LHS. Therefore any leading zeros that exist + // in the left hand side must also exist in the result. + Known.Zero.setHighBits(LHS.countMinLeadingZeros()); return Known; } diff --git a/llvm/test/CodeGen/RISCV/rv64m-exhaustive-w-insts.ll b/llvm/test/CodeGen/RISCV/rv64m-exhaustive-w-insts.ll index bc58d04..ebad482 100644 --- a/llvm/test/CodeGen/RISCV/rv64m-exhaustive-w-insts.ll +++ b/llvm/test/CodeGen/RISCV/rv64m-exhaustive-w-insts.ll @@ -1110,8 +1110,6 @@ define signext i32 @sext_i32_remw_zext_sext_i16(i16 zeroext %0, i16 signext %1) ; RV64IM-LABEL: sext_i32_remw_zext_sext_i16: ; RV64IM: # %bb.0: ; RV64IM-NEXT: rem a0, a0, a1 -; RV64IM-NEXT: slli a0, a0, 32 -; RV64IM-NEXT: srli a0, a0, 32 ; RV64IM-NEXT: ret %3 = sext i16 %1 to i32 %4 = zext i16 %0 to i32 -- 2.7.4