[llvm] 481ce81 - IR: Stop requiring nsz to reassociate fmul (#171726)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Dec 11 03:11:05 PST 2025
Author: Matt Arsenault
Date: 2025-12-11T11:11:00Z
New Revision: 481ce8169539485fd506792f86c03329c50d4a06
URL: https://github.com/llvm/llvm-project/commit/481ce8169539485fd506792f86c03329c50d4a06
DIFF: https://github.com/llvm/llvm-project/commit/481ce8169539485fd506792f86c03329c50d4a06.diff
LOG: IR: Stop requiring nsz to reassociate fmul (#171726)
nsz can only change the behavior of the sign bit.
The sign bit for fmul can be implemented as xor,
which is associative. DAGCombiner already reassociates
the multiply by 2 constants without nsz.
Fixes #64967
Added:
Modified:
llvm/lib/IR/Instruction.cpp
llvm/test/Transforms/InstCombine/2006-10-26-VectorReassoc.ll
llvm/test/Transforms/InstCombine/fdiv.ll
llvm/test/Transforms/InstCombine/issue64967-reassoc-fmul.ll
Removed:
################################################################################
diff --git a/llvm/lib/IR/Instruction.cpp b/llvm/lib/IR/Instruction.cpp
index 33ca46ca1c2c6..b95c1466871bc 100644
--- a/llvm/lib/IR/Instruction.cpp
+++ b/llvm/lib/IR/Instruction.cpp
@@ -1271,6 +1271,7 @@ bool Instruction::isAssociative() const {
switch (Opcode) {
case FMul:
+ return cast<FPMathOperator>(this)->hasAllowReassoc();
case FAdd:
return cast<FPMathOperator>(this)->hasAllowReassoc() &&
cast<FPMathOperator>(this)->hasNoSignedZeros();
diff --git a/llvm/test/Transforms/InstCombine/2006-10-26-VectorReassoc.ll b/llvm/test/Transforms/InstCombine/2006-10-26-VectorReassoc.ll
index fb860a5e7bdf3..6509797e0d3dc 100644
--- a/llvm/test/Transforms/InstCombine/2006-10-26-VectorReassoc.ll
+++ b/llvm/test/Transforms/InstCombine/2006-10-26-VectorReassoc.ll
@@ -35,12 +35,10 @@ define <4 x float> @test_fmul_reassoc_nsz(<4 x float> %V) {
}
; (V * C1) * C2 => V * (C1 * C2)
-; TODO: This doesn't require 'nsz'. It should fold to V * { 1.0, 4.0e+05, -9.0, 16.0 }
define <4 x float> @test_fmul_reassoc(<4 x float> %V) {
; CHECK-LABEL: @test_fmul_reassoc(
-; CHECK-NEXT: [[TMP1:%.*]] = fmul reassoc <4 x float> [[V:%.*]], <float 1.000000e+00, float 2.000000e+00, float 3.000000e+00, float 4.000000e+00>
-; CHECK-NEXT: [[TMP2:%.*]] = fmul reassoc <4 x float> [[TMP1]], <float 1.000000e+00, float 2.000000e+05, float -3.000000e+00, float 4.000000e+00>
-; CHECK-NEXT: ret <4 x float> [[TMP2]]
+; CHECK: [[TMP1:%.*]] = fmul reassoc <4 x float> %V, <float 1.000000e+00, float 4.000000e+05, float -9.000000e+00, float 1.600000e+01>
+; CHECK-NEXT: ret <4 x float> [[TMP1]]
%Y = fmul reassoc <4 x float> %V, < float 1.000000e+00, float 2.000000e+00, float 3.000000e+00, float 4.000000e+00 >
%Z = fmul reassoc <4 x float> %Y, < float 1.000000e+00, float 2.000000e+05, float -3.000000e+00, float 4.000000e+00 >
ret <4 x float> %Z
diff --git a/llvm/test/Transforms/InstCombine/fdiv.ll b/llvm/test/Transforms/InstCombine/fdiv.ll
index 54b0bf8c50ac7..3465781e3af9d 100644
--- a/llvm/test/Transforms/InstCombine/fdiv.ll
+++ b/llvm/test/Transforms/InstCombine/fdiv.ll
@@ -525,8 +525,7 @@ define <2 x float> @div_constant_dividend2_reassoc_only(<2 x float> %x) {
define <2 x float> @div_constant_dividend3(<2 x float> %x) {
; CHECK-LABEL: @div_constant_dividend3(
-; CHECK-NEXT: [[TMP1:%.*]] = fmul reassoc arcp <2 x float> [[X:%.*]], <float 1.500000e+01, float -7.000000e+00>
-; CHECK-NEXT: [[T2:%.*]] = fmul reassoc arcp <2 x float> [[TMP1]], <float 0x3FD5555560000000, float 0x3FC24924A0000000>
+; CHECK-NEXT: [[T2:%.*]] = fmul reassoc arcp <2 x float> [[X:%.*]], <float 5.000000e+00, float -1.000000e+00>
; CHECK-NEXT: ret <2 x float> [[T2]]
;
%t1 = fdiv <2 x float> <float 3.0e0, float 7.0e0>, %x
diff --git a/llvm/test/Transforms/InstCombine/issue64967-reassoc-fmul.ll b/llvm/test/Transforms/InstCombine/issue64967-reassoc-fmul.ll
index 16f9cf2dd64c5..5d064234bf609 100644
--- a/llvm/test/Transforms/InstCombine/issue64967-reassoc-fmul.ll
+++ b/llvm/test/Transforms/InstCombine/issue64967-reassoc-fmul.ll
@@ -25,8 +25,7 @@ define float @fmul(float %x) {
define float @fmul_reassoc(float %x) {
; CHECK-LABEL: define float @fmul_reassoc(
; CHECK-SAME: float [[X:%.*]]) {
-; CHECK-NEXT: [[FMUL0:%.*]] = fmul reassoc float [[X]], 2.000000e+00
-; CHECK-NEXT: [[FMUL1:%.*]] = fmul reassoc float [[FMUL0]], 4.000000e+00
+; CHECK-NEXT: [[FMUL1:%.*]] = fmul reassoc float [[X]], 8.000000e+00
; CHECK-NEXT: ret float [[FMUL1]]
;
%fmul0 = fmul reassoc float %x, 2.0
@@ -37,8 +36,7 @@ define float @fmul_reassoc(float %x) {
define <2 x float> @fmul_reassoc_v2(<2 x float> %x) {
; CHECK-LABEL: define <2 x float> @fmul_reassoc_v2(
; CHECK-SAME: <2 x float> [[X:%.*]]) {
-; CHECK-NEXT: [[FMUL0:%.*]] = fmul reassoc <2 x float> [[X]], splat (float 2.000000e+00)
-; CHECK-NEXT: [[FMUL1:%.*]] = fmul reassoc <2 x float> [[FMUL0]], splat (float 4.000000e+00)
+; CHECK-NEXT: [[FMUL1:%.*]] = fmul reassoc <2 x float> [[X]], splat (float 8.000000e+00)
; CHECK-NEXT: ret <2 x float> [[FMUL1]]
;
%fmul0 = fmul reassoc <2 x float> %x, splat (float 2.0)
@@ -54,8 +52,7 @@ define <2 x float> @fmul_reassoc_v2(<2 x float> %x) {
define float @fmul_reassoc_negative_0(float %x) {
; CHECK-LABEL: define float @fmul_reassoc_negative_0(
; CHECK-SAME: float [[X:%.*]]) {
-; CHECK-NEXT: [[FMUL0:%.*]] = fmul reassoc float [[X]], 2.000000e+00
-; CHECK-NEXT: [[FMUL1:%.*]] = fmul reassoc float [[FMUL0]], -4.000000e+00
+; CHECK-NEXT: [[FMUL1:%.*]] = fmul reassoc float [[X]], -8.000000e+00
; CHECK-NEXT: ret float [[FMUL1]]
;
%fmul0 = fmul reassoc float %x, 2.0
@@ -71,8 +68,7 @@ define float @fmul_reassoc_negative_0(float %x) {
define float @fmul_reassoc_negative_1(float %x) {
; CHECK-LABEL: define float @fmul_reassoc_negative_1(
; CHECK-SAME: float [[X:%.*]]) {
-; CHECK-NEXT: [[FMUL0:%.*]] = fmul reassoc float [[X]], -2.000000e+00
-; CHECK-NEXT: [[FMUL1:%.*]] = fmul reassoc float [[FMUL0]], 4.000000e+00
+; CHECK-NEXT: [[FMUL1:%.*]] = fmul reassoc float [[X]], -8.000000e+00
; CHECK-NEXT: ret float [[FMUL1]]
;
%fmul0 = fmul reassoc float %x, -2.0
@@ -95,8 +91,7 @@ define float @fmul_reassoc_nsz(float %x) {
define float @fmul_reassoc_posk_neg0(float %x) {
; CHECK-LABEL: define float @fmul_reassoc_posk_neg0(
; CHECK-SAME: float [[X:%.*]]) {
-; CHECK-NEXT: [[FMUL0:%.*]] = fmul reassoc float [[X]], 4.000000e+00
-; CHECK-NEXT: [[FMUL1:%.*]] = fmul reassoc float [[FMUL0]], -0.000000e+00
+; CHECK-NEXT: [[FMUL1:%.*]] = fmul reassoc float [[X]], -0.000000e+00
; CHECK-NEXT: ret float [[FMUL1]]
;
%fmul0 = fmul reassoc float %x, 4.0
@@ -108,8 +103,7 @@ define float @fmul_reassoc_neg0_posk(float %x) {
; CHECK-LABEL: define float @fmul_reassoc_neg0_posk(
; CHECK-SAME: float [[X:%.*]]) {
; CHECK-NEXT: [[FMUL0:%.*]] = fmul reassoc float [[X]], -0.000000e+00
-; CHECK-NEXT: [[FMUL1:%.*]] = fmul reassoc float [[FMUL0]], 4.000000e+00
-; CHECK-NEXT: ret float [[FMUL1]]
+; CHECK-NEXT: ret float [[FMUL0]]
;
%fmul0 = fmul reassoc float %x, -0.0
%fmul1 = fmul reassoc float %fmul0, 4.0
More information about the llvm-commits
mailing list