Skip to content

Commit a7f8f32

Browse files
committed
IR: Stop requiring nsz to reassociate fmul
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
1 parent e7a02eb commit a7f8f32

File tree

4 files changed

+10
-18
lines changed

4 files changed

+10
-18
lines changed

llvm/lib/IR/Instruction.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1271,6 +1271,7 @@ bool Instruction::isAssociative() const {
12711271

12721272
switch (Opcode) {
12731273
case FMul:
1274+
return cast<FPMathOperator>(this)->hasAllowReassoc();
12741275
case FAdd:
12751276
return cast<FPMathOperator>(this)->hasAllowReassoc() &&
12761277
cast<FPMathOperator>(this)->hasNoSignedZeros();

llvm/test/Transforms/InstCombine/2006-10-26-VectorReassoc.ll

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,10 @@ define <4 x float> @test_fmul_reassoc_nsz(<4 x float> %V) {
3535
}
3636

3737
; (V * C1) * C2 => V * (C1 * C2)
38-
; TODO: This doesn't require 'nsz'. It should fold to V * { 1.0, 4.0e+05, -9.0, 16.0 }
3938
define <4 x float> @test_fmul_reassoc(<4 x float> %V) {
4039
; CHECK-LABEL: @test_fmul_reassoc(
41-
; 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>
42-
; 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>
43-
; CHECK-NEXT: ret <4 x float> [[TMP2]]
40+
; CHECK: [[TMP1:%.*]] = fmul reassoc <4 x float> %V, <float 1.000000e+00, float 4.000000e+05, float -9.000000e+00, float 1.600000e+01>
41+
; CHECK-NEXT: ret <4 x float> [[TMP1]]
4442
%Y = fmul reassoc <4 x float> %V, < float 1.000000e+00, float 2.000000e+00, float 3.000000e+00, float 4.000000e+00 >
4543
%Z = fmul reassoc <4 x float> %Y, < float 1.000000e+00, float 2.000000e+05, float -3.000000e+00, float 4.000000e+00 >
4644
ret <4 x float> %Z

llvm/test/Transforms/InstCombine/fdiv.ll

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -525,8 +525,7 @@ define <2 x float> @div_constant_dividend2_reassoc_only(<2 x float> %x) {
525525

526526
define <2 x float> @div_constant_dividend3(<2 x float> %x) {
527527
; CHECK-LABEL: @div_constant_dividend3(
528-
; CHECK-NEXT: [[TMP1:%.*]] = fmul reassoc arcp <2 x float> [[X:%.*]], <float 1.500000e+01, float -7.000000e+00>
529-
; CHECK-NEXT: [[T2:%.*]] = fmul reassoc arcp <2 x float> [[TMP1]], <float 0x3FD5555560000000, float 0x3FC24924A0000000>
528+
; CHECK-NEXT: [[T2:%.*]] = fmul reassoc arcp <2 x float> [[X:%.*]], <float 5.000000e+00, float -1.000000e+00>
530529
; CHECK-NEXT: ret <2 x float> [[T2]]
531530
;
532531
%t1 = fdiv <2 x float> <float 3.0e0, float 7.0e0>, %x

llvm/test/Transforms/InstCombine/issue64967-reassoc-fmul.ll

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,7 @@ define float @fmul(float %x) {
2525
define float @fmul_reassoc(float %x) {
2626
; CHECK-LABEL: define float @fmul_reassoc(
2727
; CHECK-SAME: float [[X:%.*]]) {
28-
; CHECK-NEXT: [[FMUL0:%.*]] = fmul reassoc float [[X]], 2.000000e+00
29-
; CHECK-NEXT: [[FMUL1:%.*]] = fmul reassoc float [[FMUL0]], 4.000000e+00
28+
; CHECK-NEXT: [[FMUL1:%.*]] = fmul reassoc float [[X]], 8.000000e+00
3029
; CHECK-NEXT: ret float [[FMUL1]]
3130
;
3231
%fmul0 = fmul reassoc float %x, 2.0
@@ -37,8 +36,7 @@ define float @fmul_reassoc(float %x) {
3736
define <2 x float> @fmul_reassoc_v2(<2 x float> %x) {
3837
; CHECK-LABEL: define <2 x float> @fmul_reassoc_v2(
3938
; CHECK-SAME: <2 x float> [[X:%.*]]) {
40-
; CHECK-NEXT: [[FMUL0:%.*]] = fmul reassoc <2 x float> [[X]], splat (float 2.000000e+00)
41-
; CHECK-NEXT: [[FMUL1:%.*]] = fmul reassoc <2 x float> [[FMUL0]], splat (float 4.000000e+00)
39+
; CHECK-NEXT: [[FMUL1:%.*]] = fmul reassoc <2 x float> [[X]], splat (float 8.000000e+00)
4240
; CHECK-NEXT: ret <2 x float> [[FMUL1]]
4341
;
4442
%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) {
5452
define float @fmul_reassoc_negative_0(float %x) {
5553
; CHECK-LABEL: define float @fmul_reassoc_negative_0(
5654
; CHECK-SAME: float [[X:%.*]]) {
57-
; CHECK-NEXT: [[FMUL0:%.*]] = fmul reassoc float [[X]], 2.000000e+00
58-
; CHECK-NEXT: [[FMUL1:%.*]] = fmul reassoc float [[FMUL0]], -4.000000e+00
55+
; CHECK-NEXT: [[FMUL1:%.*]] = fmul reassoc float [[X]], -8.000000e+00
5956
; CHECK-NEXT: ret float [[FMUL1]]
6057
;
6158
%fmul0 = fmul reassoc float %x, 2.0
@@ -71,8 +68,7 @@ define float @fmul_reassoc_negative_0(float %x) {
7168
define float @fmul_reassoc_negative_1(float %x) {
7269
; CHECK-LABEL: define float @fmul_reassoc_negative_1(
7370
; CHECK-SAME: float [[X:%.*]]) {
74-
; CHECK-NEXT: [[FMUL0:%.*]] = fmul reassoc float [[X]], -2.000000e+00
75-
; CHECK-NEXT: [[FMUL1:%.*]] = fmul reassoc float [[FMUL0]], 4.000000e+00
71+
; CHECK-NEXT: [[FMUL1:%.*]] = fmul reassoc float [[X]], -8.000000e+00
7672
; CHECK-NEXT: ret float [[FMUL1]]
7773
;
7874
%fmul0 = fmul reassoc float %x, -2.0
@@ -95,8 +91,7 @@ define float @fmul_reassoc_nsz(float %x) {
9591
define float @fmul_reassoc_posk_neg0(float %x) {
9692
; CHECK-LABEL: define float @fmul_reassoc_posk_neg0(
9793
; CHECK-SAME: float [[X:%.*]]) {
98-
; CHECK-NEXT: [[FMUL0:%.*]] = fmul reassoc float [[X]], 4.000000e+00
99-
; CHECK-NEXT: [[FMUL1:%.*]] = fmul reassoc float [[FMUL0]], -0.000000e+00
94+
; CHECK-NEXT: [[FMUL1:%.*]] = fmul reassoc float [[X]], -0.000000e+00
10095
; CHECK-NEXT: ret float [[FMUL1]]
10196
;
10297
%fmul0 = fmul reassoc float %x, 4.0
@@ -108,8 +103,7 @@ define float @fmul_reassoc_neg0_posk(float %x) {
108103
; CHECK-LABEL: define float @fmul_reassoc_neg0_posk(
109104
; CHECK-SAME: float [[X:%.*]]) {
110105
; CHECK-NEXT: [[FMUL0:%.*]] = fmul reassoc float [[X]], -0.000000e+00
111-
; CHECK-NEXT: [[FMUL1:%.*]] = fmul reassoc float [[FMUL0]], 4.000000e+00
112-
; CHECK-NEXT: ret float [[FMUL1]]
106+
; CHECK-NEXT: ret float [[FMUL0]]
113107
;
114108
%fmul0 = fmul reassoc float %x, -0.0
115109
%fmul1 = fmul reassoc float %fmul0, 4.0

0 commit comments

Comments
 (0)