-
Notifications
You must be signed in to change notification settings - Fork 14.9k
[RISCV][GISel] Add initial support for rvv intrinsics #156415
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
This pr removes the falling back to SDISel of rvv intrinsics and marks them legalized in the legalize pass.
You can test this locally with the following command:git diff -U0 --pickaxe-regex -S '([^a-zA-Z0-9#_-]undef[^a-zA-Z0-9_-]|UndefValue::get)' 'HEAD~1' HEAD llvm/test/CodeGen/RISCV/GlobalISel/rvv/vfadd.ll llvm/lib/Target/RISCV/GISel/RISCVLegalizerInfo.cpp llvm/lib/Target/RISCV/RISCVISelLowering.cpp llvm/test/CodeGen/RISCV/GlobalISel/irtranslator/fallback.ll The following files introduce new uses of undef:
Undef is now deprecated and should only be used in the rare cases where no replacement is possible. For example, a load of uninitialized memory yields In tests, avoid using For example, this is considered a bad practice: define void @fn() {
...
br i1 undef, ...
} Please use the following instead: define void @fn(i1 %cond) {
...
br i1 %cond, ...
} Please refer to the Undefined Behavior Manual for more information. |
const RISCVVIntrinsicsTable::RISCVVIntrinsicInfo *II = | ||
RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IntrinsicID); | ||
|
||
if (II) { | ||
return true; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If II
is otherwise unused, this should be:
const RISCVVIntrinsicsTable::RISCVVIntrinsicInfo *II = | |
RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IntrinsicID); | |
if (II) { | |
return true; | |
} | |
if (RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IntrinsicID)) | |
return true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed, I was thinking to use the intrinsic info to identify which rvv intrinsics need specific legalization, since the change is not in this pr, I changed this to the suggested form.
if (Op == Instruction::Call) { | ||
const CallInst &CI = cast<CallInst>(Inst); | ||
const Function *F = CI.getCalledFunction(); | ||
Intrinsic::ID ID = F ? F->getIntrinsicID() : Intrinsic::not_intrinsic; | ||
|
||
const RISCVVIntrinsicsTable::RISCVVIntrinsicInfo *II = | ||
RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(ID); | ||
// Mark RVV intrinsic is supported. | ||
if (II) | ||
return false; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (Op == Instruction::Call) { | |
const CallInst &CI = cast<CallInst>(Inst); | |
const Function *F = CI.getCalledFunction(); | |
Intrinsic::ID ID = F ? F->getIntrinsicID() : Intrinsic::not_intrinsic; | |
const RISCVVIntrinsicsTable::RISCVVIntrinsicInfo *II = | |
RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(ID); | |
// Mark RVV intrinsic is supported. | |
if (II) | |
return false; | |
} | |
if (auto *II = dyn_cast<IntrinsicInst>(&Inst)) { | |
// Mark RVV intrinsic as supported. | |
if (RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(II->getIntrinsicID())) | |
return false; | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed.
What about i64 scalar operands on RV32? |
; RUN: sed 's/iXLen/i64/g' %s | llc -mtriple=riscv64 -mattr=+v,+zfhmin,+zvfh \ | ||
; RUN: -verify-machineinstrs -target-abi=lp64d -global-isel | FileCheck %s | ||
|
||
declare <vscale x 1 x half> @llvm.riscv.vfadd.nxv1f16.nxv1f16( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we no longer need to declare intrinsics
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks to point this, this test case is just copied from the SDISel case, maybe we need to refactor them all.
<vscale x 1 x half>, | ||
iXLen, iXLen); | ||
|
||
define <vscale x 1 x half> @intrinsic_vfadd_vv_nxv1f16_nxv1f16_nxv1f16(<vscale x 1 x half> %0, <vscale x 1 x half> %1, iXLen %2) nounwind { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: for most of the intrinsics here, their operands should have the same type, so a function like intrinsic_vfadd_vv_nxv1f16
should suffice
✅ With the latest revision this PR passed the C/C++ code formatter. |
Not only the i64 scalar operands on RV32, all integer scalars that is not XLen bits should be legalized. I plan to implement these in the next pr to support vx and vf form intrinsics. |
if (RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IntrinsicID)) { | ||
return true; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: llvm style prefers simple stmt bodies don't have {}
s
if (RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IntrinsicID)) { | |
return true; | |
} | |
if (RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(IntrinsicID)) | |
return true; |
// Mark RVV intrinsic as supported. | ||
if (RISCVVIntrinsicsTable::getRISCVVIntrinsicInfo(II->getIntrinsicID())) | ||
return false; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
okay to keep them here though, because of the comment.
This pr removes the falling back to SDISel of rvv intrinsics and marks them legalized in the legalize pass. Another pr would be created for regbankselect pass to make vf form intriniscs have the right scalar register bank.