This is an archive of the discontinued LLVM Phabricator instance.

[RISCV] Add patterns to MIR sign-extension removal pass.
ClosedPublic

Authored by mohammed-nurulhoque on Jan 17 2022, 4:09 AM.

Details

Summary

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

Diff Detail

Event Timeline

mohammed-nurulhoque requested review of this revision.Jan 17 2022, 4:09 AM

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.

craig.topper added inline comments.Jan 17 2022, 9:55 AM
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
0xffffffffffffffff % 0x8000000000000000 = 0x7fffffffffffffff

craig.topper added inline comments.Jan 17 2022, 11:40 AM
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
}
mohammed-nurulhoque marked 3 inline comments as done.Jan 18 2022, 4:18 AM
This revision is now accepted and ready to land.Jan 18 2022, 8:10 PM

Thanks. Could you please commit the changes as I don't have commit access?

Thanks. Could you please commit the changes as I don't have commit access?

Yes. Can you provide your name and email as you'd like it in the git log.

Mohammed Nurul Hoque
mohammed.nurulhoque@imgtec.com

This revision was landed with ongoing or failed builds.Jan 19 2022, 5:34 PM
This revision was automatically updated to reflect the committed changes.