This is an archive of the discontinued LLVM Phabricator instance.

[RISCV] Match ext + ext + srem + trunc to vrem.vv
ClosedPublic

Authored by LWenH on Jul 31 2023, 6:12 AM.

Details

Summary

This patch match the SDNode pattern:" trunc (srem(sext, ext))" to vrem.vv. This could remove the extra "vsext" ,"vnsrl" and the "vsetvli" instructions in the case like "c[i] = a[i] % b[i]", where the element types in the array are all int8_t or int16_t at the same time.

For element types like uint8_t or uint16_t, the "zext + zext + urem + trunc" based redundant IR have been removed during the instCombine pass, this is because the urem operation won't lead to the overflowed in the LLVM. However, for signed types, the instCombine pass can not remove such patterns due to the potential for Undefined Behavior in LLVM IR. Taking an example, -128 % -1 will lead to the Undefined Behaviour(overflowed) under the i8 type in LLVM IR, but this situation doesn't occur for i32. To address this, LLVM first signed extends the operands for srem to i32 to prevent the UB.

For RVV, such overflow operations are already defined by the specification and yield deterministic output for extreme inputs. For example, based on the spec, for the i8 type, -128 % -1 actually have 0 as the output result under the overflowed situation. Therefore, it would be able to match such pattern in the instruction selection phase for the rvv backend rather than removing them in the target-independent optimization passes like instCombine pass.

This patch only handle the sign_ext circumstances for srem. For more information about the C test cases compared with GCC, please see : https://gcc.godbolt.org/z/MWzE7WaT4

Diff Detail

Event Timeline

LWenH created this revision.Jul 31 2023, 6:12 AM
LWenH requested review of this revision.Jul 31 2023, 6:12 AM
LWenH edited the summary of this revision. (Show Details)Jul 31 2023, 6:22 AM
LWenH edited the summary of this revision. (Show Details)Jul 31 2023, 6:47 AM
Jim added a comment.Jul 31 2023, 6:52 AM

Could you have pre-commit test for easily showing the change of this patch?

llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td
2236 ↗(On Diff #545603)

indents doesn't look similar with other pat definition.

LWenH added inline comments.Jul 31 2023, 7:33 AM
llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td
2236 ↗(On Diff #545603)

Sure, but I'm not quite familiar with such process of pre-commit test in LLVM, could you give me some hint about the pre-commit test here or how to do so?

craig.topper added inline comments.Jul 31 2023, 11:54 AM
llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td
2236 ↗(On Diff #545603)

Make a separate phabricator review with the new test cases. Update this patch to show how those tests are changed. Add the pre-commit patch as a parent of this patch.

It would be good if the description said why this can't be done before the instruction selection phase for signed.

LWenH updated this revision to Diff 548933.EditedAug 10 2023, 2:25 AM
LWenH retitled this revision from [RISCV] Match ext_vl + ext_vl + srem + trunc_vl to vrem.vv to [RISCV] Match ext + ext + srem + trunc to vrem.vv.
LWenH edited the summary of this revision. (Show Details)

Address @craig.topper and @Jim 's comments. Update and add precommit test for this patch.

Actually, I think these signed operation can't be removed before the instruction selection phase. These signed extension and trunc operation pair in LLVM system is to prevent Undefined Behavior. Taking an example, -128 % -1 will lead to the Undefined Behaviour(overflowed) under the i8 type in LLVM IR, but this won't happen for i32. So LLVM first extend this to i32 to prevent the UB. For the unsigned, such pattern can be able to removed during the instcombine pass, this is because the urem operation won't lead to the overflowed in LLVM. For RVV, such overflow operation has been defined in the spec and have the determined output. For example, base on the spec, for the i8 type, -128 % -1 actually have 0 as the output result. So, I'm thinking for the rvv backend, we can remove such pattern to shrink the codesize.

Address @craig.topper and @Jim 's comments. Update and add precommit test for this patch.

Actually, I think these signed operation can't be removed before the instruction selection phase. These signed extension and trunc operation pair in LLVM system is to prevent Undefined Behavior. Taking an example, -128 % -1 will lead to the Undefined Behaviour(overflowed) under the i8 type in LLVM IR, but this won't happen for i32. So LLVM first extend this to i32 to prevent the UB. For the unsigned, such pattern can be able to removed during the instcombine pass, this is because the urem operation won't lead to the overflowed in LLVM. For RVV, such overflow operation has been defined in the spec and have the determined output. For example, base on the spec, for the i8 type, -128 % -1 actually have 0 as the output result. So, I'm thinking for the rvv backend, we can remove such pattern to shrink the codesize.

I agree they can't be removed before the instruction selection phase. Can you explain this in the commit message so that it will be in the git log when this is committed?

LWenH edited the summary of this revision. (Show Details)Aug 13 2023, 4:37 AM
LWenH added a comment.EditedAug 13 2023, 4:47 AM

Address @craig.topper and @Jim 's comments. Update and add precommit test for this patch.

Actually, I think these signed operation can't be removed before the instruction selection phase. These signed extension and trunc operation pair in LLVM system is to prevent Undefined Behavior. Taking an example, -128 % -1 will lead to the Undefined Behaviour(overflowed) under the i8 type in LLVM IR, but this won't happen for i32. So LLVM first extend this to i32 to prevent the UB. For the unsigned, such pattern can be able to removed during the instcombine pass, this is because the urem operation won't lead to the overflowed in LLVM. For RVV, such overflow operation has been defined in the spec and have the determined output. For example, base on the spec, for the i8 type, -128 % -1 actually have 0 as the output result. So, I'm thinking for the rvv backend, we can remove such pattern to shrink the codesize.

I agree they can't be removed before the instruction selection phase. Can you explain this in the commit message so that it will be in the git log when this is committed?

Address @craig.topper's comments, update patch description about matching this pattern in the instruction selection phase. Thank you for your suggestion and the help with submitting the precommit test!

craig.topper accepted this revision.Aug 13 2023, 11:41 AM
craig.topper edited the summary of this revision. (Show Details)

LGTM

This revision is now accepted and ready to land.Aug 13 2023, 11:41 AM
LWenH added a comment.EditedAug 13 2023, 3:14 PM

@craig.topper I think I don't have the commit access for the remote repository, could you commit these patches for me? Thank you.

@craig.topper I think I don't have the commit access for the remote repository, could you commit these patches for me? Thank you.

Sure. Can you give your name and email for the git log

LWenH added a comment.Aug 13 2023, 3:48 PM

@craig.topper I think I don't have the commit access for the remote repository, could you commit these patches for me? Thank you.

Sure. Can you give your name and email for the git log

Sure, here is my contact message, username: LWenH, email: 924105575@qq.com. Thank you.