[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