[llvm] [DAGCombiner] Use KnownBits in `combineFMulOrFDivWithIntPow2` (PR #197097)
Iris Shi via llvm-commits
llvm-commits at lists.llvm.org
Tue May 12 04:19:23 PDT 2026
https://github.com/el-ev updated https://github.com/llvm/llvm-project/pull/197097
>From 6526bb772200bdca5edfbd36812ee37c78f0f02c Mon Sep 17 00:00:00 2001
From: Iris Shi <0.0 at owo.li>
Date: Tue, 12 May 2026 12:13:37 +0800
Subject: [PATCH 1/4] [DAGCombiner] Use KnownBits in
`combineFMulOrFDivWithIntPow2`
---
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 5 +-
.../X86/fold-int-pow2-with-fmul-or-fdiv.ll | 191 ++++++++++++++++++
2 files changed, 193 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 14bf2b704c4da..05492dd783738 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -19036,9 +19036,8 @@ SDValue DAGCombiner::combineFMulOrFDivWithIntPow2(SDNode *N) {
Pow2Op = Pow2Op.getOperand(0);
- // `Log2(Pow2Op) < Pow2Op.getScalarSizeInBits()`.
- // TODO: We could use knownbits to make this bound more precise.
- int MaxExpChange = Pow2Op.getValueType().getScalarSizeInBits();
+ // `Log2(Pow2Op) < Pow2Op.countMaxActiveBits()`.
+ int MaxExpChange = DAG.computeKnownBits(Pow2Op).countMaxActiveBits();
auto IsFPConstValid = [N, MaxExpChange, &Mantissa](ConstantFPSDNode *CFP) {
if (CFP == nullptr)
diff --git a/llvm/test/CodeGen/X86/fold-int-pow2-with-fmul-or-fdiv.ll b/llvm/test/CodeGen/X86/fold-int-pow2-with-fmul-or-fdiv.ll
index b3c46bc865b25..d2fb957ff53f1 100644
--- a/llvm/test/CodeGen/X86/fold-int-pow2-with-fmul-or-fdiv.ll
+++ b/llvm/test/CodeGen/X86/fold-int-pow2-with-fmul-or-fdiv.ll
@@ -1712,3 +1712,194 @@ define x86_fp80 @pr128528(i1 %cond) {
%mul = fmul x86_fp80 %conv, 0xK4007D055555555555800
ret x86_fp80 %mul
}
+
+define double @fmul_pow_shl_cnt_knownbits(i64 %cnt) nounwind {
+; CHECK-SSE-LABEL: fmul_pow_shl_cnt_knownbits:
+; CHECK-SSE: # %bb.0:
+; CHECK-SSE-NEXT: andl $15, %edi
+; CHECK-SSE-NEXT: shlq $52, %rdi
+; CHECK-SSE-NEXT: movabsq $8930638061065157010, %rax # imm = 0x7BEFFFFFFF5F3992
+; CHECK-SSE-NEXT: addq %rdi, %rax
+; CHECK-SSE-NEXT: movq %rax, %xmm0
+; CHECK-SSE-NEXT: retq
+;
+; CHECK-AVX2-LABEL: fmul_pow_shl_cnt_knownbits:
+; CHECK-AVX2: # %bb.0:
+; CHECK-AVX2-NEXT: andl $15, %edi
+; CHECK-AVX2-NEXT: shlq $52, %rdi
+; CHECK-AVX2-NEXT: movabsq $8930638061065157010, %rax # imm = 0x7BEFFFFFFF5F3992
+; CHECK-AVX2-NEXT: addq %rdi, %rax
+; CHECK-AVX2-NEXT: vmovq %rax, %xmm0
+; CHECK-AVX2-NEXT: retq
+;
+; CHECK-ONLY-AVX512F-LABEL: fmul_pow_shl_cnt_knownbits:
+; CHECK-ONLY-AVX512F: # %bb.0:
+; CHECK-ONLY-AVX512F-NEXT: andl $15, %edi
+; CHECK-ONLY-AVX512F-NEXT: shlq $52, %rdi
+; CHECK-ONLY-AVX512F-NEXT: movabsq $8930638061065157010, %rax # imm = 0x7BEFFFFFFF5F3992
+; CHECK-ONLY-AVX512F-NEXT: addq %rdi, %rax
+; CHECK-ONLY-AVX512F-NEXT: vmovq %rax, %xmm0
+; CHECK-ONLY-AVX512F-NEXT: retq
+;
+; CHECK-SKX-LABEL: fmul_pow_shl_cnt_knownbits:
+; CHECK-SKX: # %bb.0:
+; CHECK-SKX-NEXT: andb $15, %dil
+; CHECK-SKX-NEXT: movl $1, %eax
+; CHECK-SKX-NEXT: shlxq %rdi, %rax, %rax
+; CHECK-SKX-NEXT: vcvtsi2sd %rax, %xmm15, %xmm0
+; CHECK-SKX-NEXT: vmulsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
+; CHECK-SKX-NEXT: retq
+ %cnt_masked = and i64 %cnt, 15
+ %shl = shl nuw i64 1, %cnt_masked
+ %conv = uitofp i64 %shl to double
+ %mul = fmul double 9.745314e+288, %conv
+ ret double %mul
+}
+
+define double @fdiv_pow_shl_cnt_knownbits(i64 %cnt) nounwind {
+; CHECK-SSE-LABEL: fdiv_pow_shl_cnt_knownbits:
+; CHECK-SSE: # %bb.0:
+; CHECK-SSE-NEXT: andl $15, %edi
+; CHECK-SSE-NEXT: shlq $52, %rdi
+; CHECK-SSE-NEXT: movabsq $243194378260042637, %rax # imm = 0x35FFFFF9F8FD38D
+; CHECK-SSE-NEXT: subq %rdi, %rax
+; CHECK-SSE-NEXT: movq %rax, %xmm0
+; CHECK-SSE-NEXT: retq
+;
+; CHECK-AVX2-LABEL: fdiv_pow_shl_cnt_knownbits:
+; CHECK-AVX2: # %bb.0:
+; CHECK-AVX2-NEXT: andl $15, %edi
+; CHECK-AVX2-NEXT: shlq $52, %rdi
+; CHECK-AVX2-NEXT: movabsq $243194378260042637, %rax # imm = 0x35FFFFF9F8FD38D
+; CHECK-AVX2-NEXT: subq %rdi, %rax
+; CHECK-AVX2-NEXT: vmovq %rax, %xmm0
+; CHECK-AVX2-NEXT: retq
+;
+; CHECK-ONLY-AVX512F-LABEL: fdiv_pow_shl_cnt_knownbits:
+; CHECK-ONLY-AVX512F: # %bb.0:
+; CHECK-ONLY-AVX512F-NEXT: andl $15, %edi
+; CHECK-ONLY-AVX512F-NEXT: shlq $52, %rdi
+; CHECK-ONLY-AVX512F-NEXT: movabsq $243194378260042637, %rax # imm = 0x35FFFFF9F8FD38D
+; CHECK-ONLY-AVX512F-NEXT: subq %rdi, %rax
+; CHECK-ONLY-AVX512F-NEXT: vmovq %rax, %xmm0
+; CHECK-ONLY-AVX512F-NEXT: retq
+;
+; CHECK-SKX-LABEL: fdiv_pow_shl_cnt_knownbits:
+; CHECK-SKX: # %bb.0:
+; CHECK-SKX-NEXT: andb $15, %dil
+; CHECK-SKX-NEXT: movl $1, %eax
+; CHECK-SKX-NEXT: shlxq %rdi, %rax, %rax
+; CHECK-SKX-NEXT: vcvtsi2sd %rax, %xmm15, %xmm0
+; CHECK-SKX-NEXT: vmovsd {{.*#+}} xmm1 = [2.004168E-292,0.0E+0]
+; CHECK-SKX-NEXT: vdivsd %xmm0, %xmm1, %xmm0
+; CHECK-SKX-NEXT: retq
+ %cnt_masked = and i64 %cnt, 15
+ %shl = shl nuw i64 1, %cnt_masked
+ %conv = uitofp i64 %shl to double
+ %mul = fdiv double 2.004168e-292, %conv
+ ret double %mul
+}
+
+; Negative: 1010+16=1026 >= 1023
+define double @fmul_pow_shl_cnt_fail_knownbits_bad_exp(i64 %cnt) nounwind {
+; CHECK-SSE-LABEL: fmul_pow_shl_cnt_fail_knownbits_bad_exp:
+; CHECK-SSE: # %bb.0:
+; CHECK-SSE-NEXT: movq %rdi, %rcx
+; CHECK-SSE-NEXT: andb $15, %cl
+; CHECK-SSE-NEXT: movl $1, %eax
+; CHECK-SSE-NEXT: # kill: def $cl killed $cl killed $rcx
+; CHECK-SSE-NEXT: shll %cl, %eax
+; CHECK-SSE-NEXT: cvtsi2sd %eax, %xmm0
+; CHECK-SSE-NEXT: mulsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
+; CHECK-SSE-NEXT: retq
+;
+; CHECK-AVX2-LABEL: fmul_pow_shl_cnt_fail_knownbits_bad_exp:
+; CHECK-AVX2: # %bb.0:
+; CHECK-AVX2-NEXT: movq %rdi, %rcx
+; CHECK-AVX2-NEXT: andb $15, %cl
+; CHECK-AVX2-NEXT: movl $1, %eax
+; CHECK-AVX2-NEXT: # kill: def $cl killed $cl killed $rcx
+; CHECK-AVX2-NEXT: shll %cl, %eax
+; CHECK-AVX2-NEXT: vcvtsi2sd %eax, %xmm15, %xmm0
+; CHECK-AVX2-NEXT: vmulsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
+; CHECK-AVX2-NEXT: retq
+;
+; CHECK-ONLY-AVX512F-LABEL: fmul_pow_shl_cnt_fail_knownbits_bad_exp:
+; CHECK-ONLY-AVX512F: # %bb.0:
+; CHECK-ONLY-AVX512F-NEXT: movq %rdi, %rcx
+; CHECK-ONLY-AVX512F-NEXT: andb $15, %cl
+; CHECK-ONLY-AVX512F-NEXT: movl $1, %eax
+; CHECK-ONLY-AVX512F-NEXT: # kill: def $cl killed $cl killed $rcx
+; CHECK-ONLY-AVX512F-NEXT: shll %cl, %eax
+; CHECK-ONLY-AVX512F-NEXT: vcvtsi2sd %eax, %xmm15, %xmm0
+; CHECK-ONLY-AVX512F-NEXT: vmulsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
+; CHECK-ONLY-AVX512F-NEXT: retq
+;
+; CHECK-SKX-LABEL: fmul_pow_shl_cnt_fail_knownbits_bad_exp:
+; CHECK-SKX: # %bb.0:
+; CHECK-SKX-NEXT: andb $15, %dil
+; CHECK-SKX-NEXT: movl $1, %eax
+; CHECK-SKX-NEXT: shlxq %rdi, %rax, %rax
+; CHECK-SKX-NEXT: vcvtsi2sd %rax, %xmm15, %xmm0
+; CHECK-SKX-NEXT: vmulsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
+; CHECK-SKX-NEXT: retq
+ %cnt_masked = and i64 %cnt, 15
+ %shl = shl nuw i64 1, %cnt_masked
+ %conv = uitofp i64 %shl to double
+ %mul = fmul double 0x7F18000000000000, %conv
+ ret double %mul
+}
+
+; Negative: -1008-16=-1024 <= -1022
+define double @fdiv_pow_shl_cnt_fail_knownbits_bad_exp(i64 %cnt) nounwind {
+; CHECK-SSE-LABEL: fdiv_pow_shl_cnt_fail_knownbits_bad_exp:
+; CHECK-SSE: # %bb.0:
+; CHECK-SSE-NEXT: movq %rdi, %rcx
+; CHECK-SSE-NEXT: andb $15, %cl
+; CHECK-SSE-NEXT: movl $1, %eax
+; CHECK-SSE-NEXT: # kill: def $cl killed $cl killed $rcx
+; CHECK-SSE-NEXT: shll %cl, %eax
+; CHECK-SSE-NEXT: cvtsi2sd %eax, %xmm1
+; CHECK-SSE-NEXT: movsd {{.*#+}} xmm0 = [5.4683415146672981E-304,0.0E+0]
+; CHECK-SSE-NEXT: divsd %xmm1, %xmm0
+; CHECK-SSE-NEXT: retq
+;
+; CHECK-AVX2-LABEL: fdiv_pow_shl_cnt_fail_knownbits_bad_exp:
+; CHECK-AVX2: # %bb.0:
+; CHECK-AVX2-NEXT: movq %rdi, %rcx
+; CHECK-AVX2-NEXT: andb $15, %cl
+; CHECK-AVX2-NEXT: movl $1, %eax
+; CHECK-AVX2-NEXT: # kill: def $cl killed $cl killed $rcx
+; CHECK-AVX2-NEXT: shll %cl, %eax
+; CHECK-AVX2-NEXT: vcvtsi2sd %eax, %xmm15, %xmm0
+; CHECK-AVX2-NEXT: vmovsd {{.*#+}} xmm1 = [5.4683415146672981E-304,0.0E+0]
+; CHECK-AVX2-NEXT: vdivsd %xmm0, %xmm1, %xmm0
+; CHECK-AVX2-NEXT: retq
+;
+; CHECK-ONLY-AVX512F-LABEL: fdiv_pow_shl_cnt_fail_knownbits_bad_exp:
+; CHECK-ONLY-AVX512F: # %bb.0:
+; CHECK-ONLY-AVX512F-NEXT: movq %rdi, %rcx
+; CHECK-ONLY-AVX512F-NEXT: andb $15, %cl
+; CHECK-ONLY-AVX512F-NEXT: movl $1, %eax
+; CHECK-ONLY-AVX512F-NEXT: # kill: def $cl killed $cl killed $rcx
+; CHECK-ONLY-AVX512F-NEXT: shll %cl, %eax
+; CHECK-ONLY-AVX512F-NEXT: vcvtsi2sd %eax, %xmm15, %xmm0
+; CHECK-ONLY-AVX512F-NEXT: vmovsd {{.*#+}} xmm1 = [5.4683415146672981E-304,0.0E+0]
+; CHECK-ONLY-AVX512F-NEXT: vdivsd %xmm0, %xmm1, %xmm0
+; CHECK-ONLY-AVX512F-NEXT: retq
+;
+; CHECK-SKX-LABEL: fdiv_pow_shl_cnt_fail_knownbits_bad_exp:
+; CHECK-SKX: # %bb.0:
+; CHECK-SKX-NEXT: andb $15, %dil
+; CHECK-SKX-NEXT: movl $1, %eax
+; CHECK-SKX-NEXT: shlxq %rdi, %rax, %rax
+; CHECK-SKX-NEXT: vcvtsi2sd %rax, %xmm15, %xmm0
+; CHECK-SKX-NEXT: vmovsd {{.*#+}} xmm1 = [5.4683415146672981E-304,0.0E+0]
+; CHECK-SKX-NEXT: vdivsd %xmm0, %xmm1, %xmm0
+; CHECK-SKX-NEXT: retq
+ %cnt_masked = and i64 %cnt, 15
+ %shl = shl nuw i64 1, %cnt_masked
+ %conv = uitofp i64 %shl to double
+ %mul = fdiv double 0x00F8000000000000, %conv
+ ret double %mul
+}
>From 53b4b2740b60a4fe2366e48d314cfcc2923ed62e Mon Sep 17 00:00:00 2001
From: Iris Shi <0.0 at owo.li>
Date: Tue, 12 May 2026 12:14:20 +0800
Subject: [PATCH 2/4] update test
---
.../X86/fold-int-pow2-with-fmul-or-fdiv.ll | 69 +++++--------------
1 file changed, 16 insertions(+), 53 deletions(-)
diff --git a/llvm/test/CodeGen/X86/fold-int-pow2-with-fmul-or-fdiv.ll b/llvm/test/CodeGen/X86/fold-int-pow2-with-fmul-or-fdiv.ll
index d2fb957ff53f1..c757e67d1b1c8 100644
--- a/llvm/test/CodeGen/X86/fold-int-pow2-with-fmul-or-fdiv.ll
+++ b/llvm/test/CodeGen/X86/fold-int-pow2-with-fmul-or-fdiv.ll
@@ -1723,32 +1723,14 @@ define double @fmul_pow_shl_cnt_knownbits(i64 %cnt) nounwind {
; CHECK-SSE-NEXT: movq %rax, %xmm0
; CHECK-SSE-NEXT: retq
;
-; CHECK-AVX2-LABEL: fmul_pow_shl_cnt_knownbits:
-; CHECK-AVX2: # %bb.0:
-; CHECK-AVX2-NEXT: andl $15, %edi
-; CHECK-AVX2-NEXT: shlq $52, %rdi
-; CHECK-AVX2-NEXT: movabsq $8930638061065157010, %rax # imm = 0x7BEFFFFFFF5F3992
-; CHECK-AVX2-NEXT: addq %rdi, %rax
-; CHECK-AVX2-NEXT: vmovq %rax, %xmm0
-; CHECK-AVX2-NEXT: retq
-;
-; CHECK-ONLY-AVX512F-LABEL: fmul_pow_shl_cnt_knownbits:
-; CHECK-ONLY-AVX512F: # %bb.0:
-; CHECK-ONLY-AVX512F-NEXT: andl $15, %edi
-; CHECK-ONLY-AVX512F-NEXT: shlq $52, %rdi
-; CHECK-ONLY-AVX512F-NEXT: movabsq $8930638061065157010, %rax # imm = 0x7BEFFFFFFF5F3992
-; CHECK-ONLY-AVX512F-NEXT: addq %rdi, %rax
-; CHECK-ONLY-AVX512F-NEXT: vmovq %rax, %xmm0
-; CHECK-ONLY-AVX512F-NEXT: retq
-;
-; CHECK-SKX-LABEL: fmul_pow_shl_cnt_knownbits:
-; CHECK-SKX: # %bb.0:
-; CHECK-SKX-NEXT: andb $15, %dil
-; CHECK-SKX-NEXT: movl $1, %eax
-; CHECK-SKX-NEXT: shlxq %rdi, %rax, %rax
-; CHECK-SKX-NEXT: vcvtsi2sd %rax, %xmm15, %xmm0
-; CHECK-SKX-NEXT: vmulsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
-; CHECK-SKX-NEXT: retq
+; CHECK-AVX-LABEL: fmul_pow_shl_cnt_knownbits:
+; CHECK-AVX: # %bb.0:
+; CHECK-AVX-NEXT: andl $15, %edi
+; CHECK-AVX-NEXT: shlq $52, %rdi
+; CHECK-AVX-NEXT: movabsq $8930638061065157010, %rax # imm = 0x7BEFFFFFFF5F3992
+; CHECK-AVX-NEXT: addq %rdi, %rax
+; CHECK-AVX-NEXT: vmovq %rax, %xmm0
+; CHECK-AVX-NEXT: retq
%cnt_masked = and i64 %cnt, 15
%shl = shl nuw i64 1, %cnt_masked
%conv = uitofp i64 %shl to double
@@ -1766,33 +1748,14 @@ define double @fdiv_pow_shl_cnt_knownbits(i64 %cnt) nounwind {
; CHECK-SSE-NEXT: movq %rax, %xmm0
; CHECK-SSE-NEXT: retq
;
-; CHECK-AVX2-LABEL: fdiv_pow_shl_cnt_knownbits:
-; CHECK-AVX2: # %bb.0:
-; CHECK-AVX2-NEXT: andl $15, %edi
-; CHECK-AVX2-NEXT: shlq $52, %rdi
-; CHECK-AVX2-NEXT: movabsq $243194378260042637, %rax # imm = 0x35FFFFF9F8FD38D
-; CHECK-AVX2-NEXT: subq %rdi, %rax
-; CHECK-AVX2-NEXT: vmovq %rax, %xmm0
-; CHECK-AVX2-NEXT: retq
-;
-; CHECK-ONLY-AVX512F-LABEL: fdiv_pow_shl_cnt_knownbits:
-; CHECK-ONLY-AVX512F: # %bb.0:
-; CHECK-ONLY-AVX512F-NEXT: andl $15, %edi
-; CHECK-ONLY-AVX512F-NEXT: shlq $52, %rdi
-; CHECK-ONLY-AVX512F-NEXT: movabsq $243194378260042637, %rax # imm = 0x35FFFFF9F8FD38D
-; CHECK-ONLY-AVX512F-NEXT: subq %rdi, %rax
-; CHECK-ONLY-AVX512F-NEXT: vmovq %rax, %xmm0
-; CHECK-ONLY-AVX512F-NEXT: retq
-;
-; CHECK-SKX-LABEL: fdiv_pow_shl_cnt_knownbits:
-; CHECK-SKX: # %bb.0:
-; CHECK-SKX-NEXT: andb $15, %dil
-; CHECK-SKX-NEXT: movl $1, %eax
-; CHECK-SKX-NEXT: shlxq %rdi, %rax, %rax
-; CHECK-SKX-NEXT: vcvtsi2sd %rax, %xmm15, %xmm0
-; CHECK-SKX-NEXT: vmovsd {{.*#+}} xmm1 = [2.004168E-292,0.0E+0]
-; CHECK-SKX-NEXT: vdivsd %xmm0, %xmm1, %xmm0
-; CHECK-SKX-NEXT: retq
+; CHECK-AVX-LABEL: fdiv_pow_shl_cnt_knownbits:
+; CHECK-AVX: # %bb.0:
+; CHECK-AVX-NEXT: andl $15, %edi
+; CHECK-AVX-NEXT: shlq $52, %rdi
+; CHECK-AVX-NEXT: movabsq $243194378260042637, %rax # imm = 0x35FFFFF9F8FD38D
+; CHECK-AVX-NEXT: subq %rdi, %rax
+; CHECK-AVX-NEXT: vmovq %rax, %xmm0
+; CHECK-AVX-NEXT: retq
%cnt_masked = and i64 %cnt, 15
%shl = shl nuw i64 1, %cnt_masked
%conv = uitofp i64 %shl to double
>From b1fe10dcc7b60d5d4f79f5faf65cb5b4e270f677 Mon Sep 17 00:00:00 2001
From: Iris Shi <0.0 at owo.li>
Date: Tue, 12 May 2026 12:17:51 +0800
Subject: [PATCH 3/4] 1
---
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 05492dd783738..115e4c3905461 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -19036,7 +19036,6 @@ SDValue DAGCombiner::combineFMulOrFDivWithIntPow2(SDNode *N) {
Pow2Op = Pow2Op.getOperand(0);
- // `Log2(Pow2Op) < Pow2Op.countMaxActiveBits()`.
int MaxExpChange = DAG.computeKnownBits(Pow2Op).countMaxActiveBits();
auto IsFPConstValid = [N, MaxExpChange, &Mantissa](ConstantFPSDNode *CFP) {
>From 0b53aa87afe1e77c93ed7c89b53f7fab867a9283 Mon Sep 17 00:00:00 2001
From: Iris Shi <0.0 at owo.li>
Date: Tue, 12 May 2026 19:19:00 +0800
Subject: [PATCH 4/4] save some knownbits computations
Co-authored-by: Copilot <copilot at github.com>
---
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 115e4c3905461..bf2a194adb539 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -19021,6 +19021,7 @@ SDValue DAGCombiner::combineFMulOrFDivWithIntPow2(SDNode *N) {
return SDValue();
SDValue ConstOp, Pow2Op;
+ KnownBits Pow2OpKnownBits;
std::optional<int> Mantissa;
auto GetConstAndPow2Ops = [&](unsigned ConstOpIdx) {
@@ -19029,14 +19030,17 @@ SDValue DAGCombiner::combineFMulOrFDivWithIntPow2(SDNode *N) {
ConstOp = peekThroughBitcasts(N->getOperand(ConstOpIdx));
Pow2Op = N->getOperand(1 - ConstOpIdx);
- if (Pow2Op.getOpcode() != ISD::UINT_TO_FP &&
- (Pow2Op.getOpcode() != ISD::SINT_TO_FP ||
- !DAG.computeKnownBits(Pow2Op).isNonNegative()))
+ unsigned Pow2Opc = Pow2Op.getOpcode();
+ if (Pow2Opc != ISD::UINT_TO_FP && Pow2Opc != ISD::SINT_TO_FP)
return false;
Pow2Op = Pow2Op.getOperand(0);
- int MaxExpChange = DAG.computeKnownBits(Pow2Op).countMaxActiveBits();
+ Pow2OpKnownBits = DAG.computeKnownBits(Pow2Op);
+ if (Pow2Opc == ISD::SINT_TO_FP && !Pow2OpKnownBits.isNonNegative())
+ return false;
+
+ int MaxExpChange = Pow2OpKnownBits.countMaxActiveBits();
auto IsFPConstValid = [N, MaxExpChange, &Mantissa](ConstantFPSDNode *CFP) {
if (CFP == nullptr)
@@ -19087,7 +19091,7 @@ SDValue DAGCombiner::combineFMulOrFDivWithIntPow2(SDNode *N) {
*DAG.getContext(),
EVT::getIntegerVT(*DAG.getContext(), VT.getScalarSizeInBits()));
- SDValue Log2 = BuildLogBase2(Pow2Op, DL, DAG.isKnownNeverZero(Pow2Op),
+ SDValue Log2 = BuildLogBase2(Pow2Op, DL, Pow2OpKnownBits.isNonZero(),
/*InexpensiveOnly*/ true, NewIntVT);
if (!Log2)
return SDValue();
More information about the llvm-commits
mailing list