[llvm] 9d6b92e - [DAG] SelectionDAG::isKnownToBeAPowerOfTwo - add ISD::TRUNCATE handling and tests (#184365)

via llvm-commits llvm-commits at lists.llvm.org
Sat Mar 28 09:50:25 PDT 2026


Author: Pranshu Goyal
Date: 2026-03-28T16:50:19Z
New Revision: 9d6b92e29fee91c827aed67b699a8a4cc38dbaac

URL: https://github.com/llvm/llvm-project/commit/9d6b92e29fee91c827aed67b699a8a4cc38dbaac
DIFF: https://github.com/llvm/llvm-project/commit/9d6b92e29fee91c827aed67b699a8a4cc38dbaac.diff

LOG: [DAG] SelectionDAG::isKnownToBeAPowerOfTwo - add ISD::TRUNCATE handling and tests (#184365)

Closes #181654

Added: 
    llvm/test/CodeGen/AArch64/knownpow2-trunc-orzero.ll

Modified: 
    llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
    llvm/test/CodeGen/X86/known-pow2.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 86afab7c45531..e53cef7b8be7f 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -4823,6 +4823,11 @@ bool SelectionDAG::isKnownToBeAPowerOfTwo(SDValue Val,
                                   Depth + 1);
   }
 
+  case ISD::TRUNCATE: {
+    return (OrZero || isKnownNeverZero(Val, Depth)) &&
+           isKnownToBeAPowerOfTwo(Val.getOperand(0), OrZero, Depth + 1);
+  }
+
   case ISD::ROTL:
   case ISD::ROTR:
     return isKnownToBeAPowerOfTwo(Val.getOperand(0), DemandedElts, OrZero,

diff  --git a/llvm/test/CodeGen/AArch64/knownpow2-trunc-orzero.ll b/llvm/test/CodeGen/AArch64/knownpow2-trunc-orzero.ll
new file mode 100644
index 0000000000000..b0c9515376286
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/knownpow2-trunc-orzero.ll
@@ -0,0 +1,34 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc < %s -mtriple=arm64-unknown-unknown-gnu | FileCheck %s --check-prefix=CHECK
+
+define i8 @pow2_trunc_orzero_false_notzero(i32 %x, i8 %z){
+; CHECK-LABEL: pow2_trunc_orzero_false_notzero:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    and w8, w1, #0xff
+; CHECK-NEXT:    and w9, w0, #0x7
+; CHECK-NEXT:    lsr w0, w8, w9
+; CHECK-NEXT:    ret
+
+  %amt = and i32 %x, 7
+  %y = shl i32 1, %amt
+  %tr = trunc i32 %y to i8
+  %div = udiv i8 %z, %tr
+  ret i8 %div
+}
+
+define i8 @pow2_trunc_orzero_false_maybezero(i32 %x, i8 %z){
+; CHECK-LABEL: pow2_trunc_orzero_false_maybezero:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    neg w8, w0
+; CHECK-NEXT:    and w9, w1, #0xff
+; CHECK-NEXT:    and w8, w0, w8
+; CHECK-NEXT:    and w8, w8, #0xff
+; CHECK-NEXT:    udiv w0, w9, w8
+; CHECK-NEXT:    ret
+
+  %neg_x = sub i32 0, %x
+  %y = and i32 %x, %neg_x
+  %tr = trunc i32 %y to i8
+  %div = udiv i8 %z, %tr
+  ret i8 %div
+}

diff  --git a/llvm/test/CodeGen/X86/known-pow2.ll b/llvm/test/CodeGen/X86/known-pow2.ll
index 2806194cff76e..5c395ec423505 100644
--- a/llvm/test/CodeGen/X86/known-pow2.ll
+++ b/llvm/test/CodeGen/X86/known-pow2.ll
@@ -1344,12 +1344,11 @@ define i32 @pow2_blsi_sub(i32 %x, i32 %a) {
 define i8 @pow2_trunc(i32 %x, i32 %a){
 ; CHECK-LABEL: pow2_trunc:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    movl %esi, %ecx
-; CHECK-NEXT:    negl %ecx
-; CHECK-NEXT:    andl %esi, %ecx
-; CHECK-NEXT:    movzbl %dil, %eax
-; CHECK-NEXT:    divb %cl
-; CHECK-NEXT:    movzbl %ah, %eax
+; CHECK-NEXT:    movl %esi, %eax
+; CHECK-NEXT:    negl %eax
+; CHECK-NEXT:    andl %esi, %eax
+; CHECK-NEXT:    decb %al
+; CHECK-NEXT:    andb %dil, %al
 ; CHECK-NEXT:    # kill: def $al killed $al killed $eax
 ; CHECK-NEXT:    retq
   %neg_a = sub i32 0, %a
@@ -1382,11 +1381,10 @@ define i8 @pow2_trunc_vec(<4 x i32> %x, <4 x i32> %a) {
 ; CHECK-NEXT:    pxor %xmm2, %xmm2
 ; CHECK-NEXT:    psubd %xmm1, %xmm2
 ; CHECK-NEXT:    pand %xmm1, %xmm2
-; CHECK-NEXT:    movd %xmm2, %ecx
-; CHECK-NEXT:    movd %xmm0, %eax
-; CHECK-NEXT:    movzbl %al, %eax
-; CHECK-NEXT:    divb %cl
-; CHECK-NEXT:    movzbl %ah, %eax
+; CHECK-NEXT:    pcmpeqd %xmm1, %xmm1
+; CHECK-NEXT:    paddb %xmm2, %xmm1
+; CHECK-NEXT:    pand %xmm0, %xmm1
+; CHECK-NEXT:    movd %xmm1, %eax
 ; CHECK-NEXT:    # kill: def $al killed $al killed $eax
 ; CHECK-NEXT:    retq
   %a.splat = shufflevector <4 x i32> %a, <4 x i32> poison, <4 x i32> zeroinitializer


        


More information about the llvm-commits mailing list