[llvm] [AMDGPU][Attributor] Infer `inreg` attribute in `AMDGPUAttributor` (PR #101609)
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 24 06:12:01 PDT 2025
================
@@ -1363,6 +1490,59 @@ static bool updateWavesPerEU(Module &M, TargetMachine &TM) {
return Changed;
}
+/// Emit the readfirstlane intrinsic for all inreg uniform function arguments at
+/// each call site. The inreg uniform attribute combination is set by
+/// AAAMDGPUUniform. This function provides a workaround for a downstream issue
+/// where failing to emit a waterfall loop for 'inreg' arguments may result in
+/// an invalid VGPR-to-SGPR copy. However, we intentionally avoid a waterfall
+/// loop for inreg uniform arguments here, because the 'inreg' attribute set by
+/// AAAMDGPUUniform guarantees uniformity, making the readfirstlane intrinsic
+/// appropriate.
+static bool emitReadFirstLaneForInregUniformArgs(Module &M) {
+ std::vector<std::pair<CallBase *, unsigned>> WorkList;
+
+ for (Function &F : M) {
+ if (F.isDeclaration())
+ continue;
+ for (Argument &Arg : F.args()) {
+ if (!Arg.hasAttribute(Attribute::InReg) || !Arg.hasAttribute("uniform"))
+ continue;
+ unsigned ArgNo = Arg.getArgNo();
+ for (Use &U : F.uses()) {
+ auto *CB = dyn_cast<CallBase>(U.getUser());
+ if (!CB)
+ continue;
+ // We will skip the call site argument when itself is an inreg argument.
+ // In this case, it will already be in SGPR.
+ if (auto *CSArg = dyn_cast<Argument>(CB->getArgOperand(ArgNo))) {
+ if (CSArg->hasAttribute(Attribute::InReg))
+ continue;
+ }
+ WorkList.emplace_back(CB, ArgNo);
+ }
+ // We don't count this as changed since it just stays within this pass.
+ Arg.removeAttr("uniform");
----------------
arsenm wrote:
I think modifying the IR and then no-oping it back to the original state caused issues in the past. Can you avoid transient state
https://github.com/llvm/llvm-project/pull/101609
More information about the llvm-commits
mailing list