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