본문으로 건너뛰기

[triton] AMD GFX1250 MachineSink 이슈 우회를 위한 fence 추가

PR 링크: triton-lang/triton#9624 상태: Merged | 변경: +55 / -0

들어가며

LLVM의 MachineSink 패스는 명령어를 사용 지점에 가까운 블록으로 이동(sink)시키는 최적화입니다. 그런데 AMDGPU barrier는 UnmodeledSideEffects만 있고 mayStore()는 없어서, MachineSinkisSafeToMove()가 선행하는 LDS load를 barrier 이후로 잘못 이동시키는 버그가 있습니다.

핵심 코드 분석

Before:

// (fence 없이 바로 atomic 연산 시작)
SmallVector<Value> resultVals(elemsPerThread);
for (size_t i = 0; i < elemsPerThread; i += vec) {

After:

if (tensorTy && targetInfo.getISAFamily() == ISAFamily::GFX1250) {
  auto asmDialectAttr = LLVM::AsmDialectAttr::get(rewriter.getContext(),
                                                  LLVM::AsmDialect::AD_ATT);
  auto asmTy = LLVM::LLVMVoidType::get(rewriter.getContext());
  LLVM::InlineAsmOp::create(
      rewriter, loc, asmTy,
      /*operands=*/ValueRange{},
      /*asm_string=*/"",
      /*constraints=*/"~{memory}",
      /*has_side_effects=*/true,
      /*is_align_stack=*/false, LLVM::TailCallKind::None, asmDialectAttr,
      /*operand_attrs=*/ArrayAttr::get(rewriter.getContext(), {}));
}

빈 inline assembly에 ~{memory} constraint를 추가합니다. 이 constraint는 mayStore()=true를 설정하므로, MachineSink의 bottom-up 탐색에서 SawStore가 세팅되어 선행 load가 이 지점을 넘어 sink되지 않습니다.

왜 이게 좋은가

  • 정확한 문제 진단: LLVM 이슈(#181708)를 정확히 참조하여 root cause를 문서화했습니다.
  • 최소 침습적 우회: 빈 assembly와 memory clobber만 사용하여 실제 코드 생성에 미치는 영향이 거의 없습니다.
  • 타겟 한정: GFX1250에서만 활성화되어 다른 아키텍처에 영향을 주지 않습니다.

정리

LLVM MachineSink가 barrier를 건너뛰어 LDS load를 잘못 이동시키는 버그의 우회 방법입니다. 빈 inline asm에 ~{memory} clobber를 넣어 mayStore 플래그를 세팅하는 최소한의 fence를 삽입합니다.

참고 자료


이 글은 AI의 도움을 받아 작성되었으며, 원본 PR의 코드 변경 사항을 기반으로 분석한 내용입니다.

댓글

관련 포스트

PR Analysis 의 다른글