Skip to content

Reassociatable fmul by constants unnecessarily requires nsz #64967

@arsenm

Description

@arsenm

These reassociatable fmuls by constants should preserve signed zero behavior, but do not fold unless nsz is attached to both multiplies

; RUN: opt -S -passes=instcombine %s

; Can't reassociate anyway
define float @fmul(float %x) {
  %fmul0 = fmul float %x, 2.0
  %fmul1 = fmul float %fmul0, 4.0
  ret float %fmul1
}

; Should be able to reassociate without nsz
; (+0 * 2) * 4 = +0
; (-0 * 2) * 4 = -0

; (+0 * 8) = +0
; (-0 * 8) = -0
define float @fmul_reassoc(float %x) {
  %fmul0 = fmul reassoc float %x, 2.0
  %fmul1 = fmul reassoc float %fmul0, 4.0
  ret float %fmul1
}

; (+0 * 2) * -4 = -0
; (-0 * 2) * -4 = +0

; (+0 * -8) = -0
; (-0 * -8) = +0
define float @fmul_reassoc_negative_0(float %x) {
  %fmul0 = fmul reassoc float %x, 2.0
  %fmul1 = fmul reassoc float %fmul0, -4.0
  ret float %fmul1
}

; (+0 * -2) * 4 = -0
; (-0 * -2) * 4 = +0

; (+0 * -8) = -0
; (-0 * -8) = +0
define float @fmul_reassoc_negative_1(float %x) {
  %fmul0 = fmul reassoc float %x, -2.0
  %fmul1 = fmul reassoc float %fmul0, 4.0
  ret float %fmul1
}

; Does reassociate already, unnecessarily requires nsz on both multiplies.
define float @fmul_reassoc_nsz(float %x) {
  %fmul0 = fmul nsz reassoc float %x, 2.0
  %fmul1 = fmul nsz reassoc float %fmul0, 4.0
  ret float %fmul1
}

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions