llvm / llvm/llvm-project

Improve AMDGPU codegen for copysign(x, fneg(y))

Open
#174,009 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

backend:AMDGPU floating-point missed-optimization
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

InstCombine tries to replace some fmuls that only change the sign bit with copysign. In the case the sign bit needs to be flipped, it inserts an fneg. This results in poor codegen.

e.g., running this through instcombine:

define float @fmul_nnan_pos_zero(float %x) {
  %fmul = fmul nnan float %x, 0.0
  ret float %fmul
}

define float @fmul_nnan_neg_zero(float %x) {
  %fmul = fmul nnan float %x, -0.0
  ret float %fmul
}

Yields

define float @fmul_nnan_pos_zero(float %x) {
  %fmul = call nnan float @llvm.copysign.f32(float 0.000000e+00, float %x)
  ret float %fmul
}

define float @fmul_nnan_neg_zero(float %x) {
  %1 = fneg nnan float %x
  %fmul = call nnan float @llvm.copysign.f32(float 0.000000e+00, float %1)
  ret float %fmul
}

Running this through codegen with llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900


fmul_nnan_pos_zero:                     ; @fmul_nnan_pos_zero
; %bb.0:
	s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
	v_and_b32_e32 v0, 0x80000000, v0
	s_setpc_b64 s[30:31]
fmul_nnan_neg_zero:                     ; @fmul_nnan_neg_zero
; %bb.0:
	s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
	v_xor_b32_e32 v0, 0x80000000, v0
	v_and_b32_e32 v0, 0x80000000, v0
	s_setpc_b64 s[30:31]

We should be able to do better in the second case

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the two examples with llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 and compare the AMDGPU assembly for the positive- and negative-zero cases. Trace the AMDGPU codegen path handling copysign with fneg, then verify that the negative-zero case no longer emits the redundant sign-bit operations while preserving the expected result.

Written by the indexing model from the issue text.

Assessment

Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.