[Intel] Stop lowering load cg/cs to !nontemporal (#7843) - #7901
Conversation
IGC turns `!nontemporal` into LSC `.uc.uc`, which over-states `cg` (L1UC_L3C) and `cs` (L1S_L3C) by also bypassing L3; that cost 1.68x on pyhpc_isoneutral_mixing at PREDICATED_LOAD=0, now 0.96x. Both now fall back to the `.ca.ca` default on the non-predicated arms of `tt.load`/`tt.descriptor_load`; the predicated arm, which carries `cg` exactly via decoration, is unchanged. Adds the missing `CS` load case.
0c8b09b to
aec9760
Compare
There was a problem hiding this comment.
Pull request overview
Stops inaccurate !nontemporal lowering for Intel XPU loads while preserving precise predicated cache controls.
Changes:
- Falls back to default caching for plain
cg/csloads. - Adds
CSpredicated-load cache-control support. - Guards layout rematerialization across unsupported regions and adds regression tests.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
third_party/intel/lib/TritonIntelGPUTransforms/Utility.cpp |
Rejects unsupported backward propagation. |
third_party/intel/lib/TritonIntelGPUToLLVM/LoadStoreOpToLLVM.cpp |
Corrects load cache-control lowering. |
test/TritonIntelGPU/combine.mlir |
Tests unsupported-region handling. |
test/Conversion/intel/load_store_to_llvm.mlir |
Tests plain and predicated cache modifiers. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| // So a plain load leaves both modifiers unannotated and runs at the | ||
| // hardware default (`.ca.ca`). Cache modifiers are performance hints, so | ||
| // caching more than asked is always safe, and it measures fastest of the | ||
| // available options on the workload above. Revisit if LLVM starts |
There was a problem hiding this comment.
Should we open an issue for LLVM?
There was a problem hiding this comment.
I found out there is an RFC and related PR (llvm/llvm-project#181612) to add to LLVM cache hint metadata. We could teach Triton to generate it (and the LLVM-SPIRV translator to support it).
This is not urgent because we are have switched tt.load and descriptor loads lowering to use predicated loads (calls) by default now. On that code path we can attach the SPIRV cache control annotation with no issues.
IGC turns
!nontemporalinto LSC.uc.uc, which over-statescg(L1UC_L3C) andcs(L1S_L3C) by also bypassing L3; that cost 1.68x on pyhpc_isoneutral_mixing atPREDICATED_LOAD=0, now 0.96x. Both now fall back to the
.ca.cadefault on thenon-predicated arms of
tt.load/tt.descriptor_load; the predicated arm, whichcarries
cgexactly via decoration, is unchanged. Adds the missingCSload case.Closes #7843