This patch adds a few instruction patterns that generate sign-extended values or propagate them, adding to the pass introduced in https://reviews.llvm.org/D116397
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
Noticed one of my patterns was redundant (merged)
Combined the independent if-statements with the switch-statement
Added tests where this patch removes sext.w that previously were not.
This is my first patch submission for LLVM and I'd appreciate your feedback if I should have done some things differently.
llvm/lib/Target/RISCV/RISCVSExtWRemoval.cpp | ||
---|---|---|
95 | Please upload patches with full context using -U999999 as noted here https://llvm.org/docs/Phabricator.html#requesting-a-review-via-the-web-interface | |
112 | ANDI was already handled in an if statement right below this switch. That code is now dead. | |
180 | This doesn't work for DIVU 0xffffffffffffffff / 2 = 0x7fffffffffffffff 0xffffffffffffffff has all sign bits, but 0x7fffffffffffffff only has 1 sign bit. It doesn't work for REMU either |
llvm/lib/Target/RISCV/RISCVSExtWRemoval.cpp | ||
---|---|---|
176 | SDIV doesn't work, but not for the reason cited. If the dividend has 32 sign bits, then it isn't INT64_MIN so the overflow case of INT64_MIN/-1 can't happen. The reason it doesn't work is because the SDIV instruction returns -2^63 for division by 0. That only has 1 sign bit. Division by 0 isn't undefined behavior at the MI level since the instruction has a definition. |
Thank you for your feedback. I fixed these errors now.
In the comment about DIV, by saying (long)0x8000 0000, I meant 0xffff fffff 8000 0000 which is a valid counter-example.
It turns out REMU doesn't work if only the dividend is sign-extended as you pointed out, but it propagates the sign-extension if both arguments are sign-extended.
I verified REM and REMU using https://alive2.llvm.org/ce/ with the following snippets. (Used i8/i16 instead of i32/i64 because it would time out otherwise, but it's the same principle).
REM:
define i16 @src(i8 %arg1, i16 %arg2) nounwind { %1 = sext i8 %arg1 to i16 %2 = srem i16 %1, %arg2 %3 = trunc i16 %2 to i8 %4 = sext i8 %3 to i16 ret i16 %4 } define i16 @tgt(i8 %arg1, i16 %arg2) nounwind { %1 = sext i8 %arg1 to i16 %2 = srem i16 %1, %arg2 ret i16 %2 }
REMU:
define i16 @src(i8 %arg1, i8 %arg2) nounwind { %1 = sext i8 %arg1 to i16 %2 = sext i8 %arg2 to i16 %3 = urem i16 %1, %2 %4 = trunc i16 %3 to i8 %5 = sext i8 %4 to i16 ret i16 %5 } define i16 @tgt(i8 %arg1, i8 %arg2) nounwind { %1 = sext i8 %arg1 to i16 %2 = sext i8 %arg2 to i16 %3 = urem i16 %1, %2 ret i16 %3 }
Please upload patches with full context using -U999999 as noted here https://llvm.org/docs/Phabricator.html#requesting-a-review-via-the-web-interface