[llvm-branch-commits] [llvm] [SPARC] Use lzcnt to implement CTLZ when we have VIS3 (PR #135715)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Thu Apr 17 08:11:33 PDT 2025


https://github.com/koachan updated https://github.com/llvm/llvm-project/pull/135715

>From 6e865810ea2acaf636a4759fd4ffc67aa3dbb848 Mon Sep 17 00:00:00 2001
From: Koakuma <koachan at protonmail.com>
Date: Thu, 17 Apr 2025 08:24:54 +0700
Subject: [PATCH 1/4] Promote i32 CTLZ when we don't have VIS3 or POPC

Created using spr 1.3.5
---
 llvm/lib/Target/Sparc/SparcISelLowering.cpp |  11 +-
 llvm/test/CodeGen/SPARC/ctlz.ll             | 182 +++-----------------
 2 files changed, 35 insertions(+), 158 deletions(-)

diff --git a/llvm/lib/Target/Sparc/SparcISelLowering.cpp b/llvm/lib/Target/Sparc/SparcISelLowering.cpp
index fa544916aebb5..e455706b0528f 100644
--- a/llvm/lib/Target/Sparc/SparcISelLowering.cpp
+++ b/llvm/lib/Target/Sparc/SparcISelLowering.cpp
@@ -1755,7 +1755,7 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM,
                        Subtarget->usePopc() ? Legal : Expand);
     setOperationAction(ISD::CTTZ , MVT::i64, Expand);
     setOperationAction(ISD::CTLZ, MVT::i64,
-                       Subtarget->isVIS3() ? Legal : LibCall);
+                       Subtarget->isVIS3() ? Legal : Expand);
     setOperationAction(ISD::BSWAP, MVT::i64, Expand);
     setOperationAction(ISD::ROTL , MVT::i64, Expand);
     setOperationAction(ISD::ROTR , MVT::i64, Expand);
@@ -1818,7 +1818,7 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM,
   setOperationAction(ISD::FMA  , MVT::f32, Expand);
   setOperationAction(ISD::CTTZ , MVT::i32, Expand);
   setOperationAction(ISD::CTLZ, MVT::i32,
-                     Subtarget->isVIS3() ? Promote : LibCall);
+                     Subtarget->isVIS3() ? Promote : Expand);
   setOperationAction(ISD::ROTL , MVT::i32, Expand);
   setOperationAction(ISD::ROTR , MVT::i32, Expand);
   setOperationAction(ISD::BSWAP, MVT::i32, Expand);
@@ -1992,6 +1992,13 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM,
   if (Subtarget->isVIS3()) {
     setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i32, Promote);
     setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i64, Legal);
+  } else if (Subtarget->usePopc()) {
+    setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i32, Expand);
+    setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i64, Expand);
+  } else {
+    setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i32,
+                       Subtarget->is64Bit() ? Promote : LibCall);
+    setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i64, LibCall);
   }
 
   setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);
diff --git a/llvm/test/CodeGen/SPARC/ctlz.ll b/llvm/test/CodeGen/SPARC/ctlz.ll
index d17b776ca0a72..3391af02e4bc0 100644
--- a/llvm/test/CodeGen/SPARC/ctlz.ll
+++ b/llvm/test/CodeGen/SPARC/ctlz.ll
@@ -6,46 +6,18 @@
 define i32 @i32_nopoison(i32 %x) nounwind {
 ; V9-LABEL: i32_nopoison:
 ; V9:       ! %bb.0:
-; V9-NEXT:    cmp %o0, 0
+; V9-NEXT:    save %sp, -176, %sp
+; V9-NEXT:    cmp %i0, 0
 ; V9-NEXT:    be %icc, .LBB0_2
 ; V9-NEXT:    nop
 ; V9-NEXT:  ! %bb.1: ! %cond.false
-; V9-NEXT:    srl %o0, 1, %o1
-; V9-NEXT:    or %o0, %o1, %o0
-; V9-NEXT:    srl %o0, 2, %o1
-; V9-NEXT:    or %o0, %o1, %o0
-; V9-NEXT:    srl %o0, 4, %o1
-; V9-NEXT:    or %o0, %o1, %o0
-; V9-NEXT:    srl %o0, 8, %o1
-; V9-NEXT:    or %o0, %o1, %o0
-; V9-NEXT:    srl %o0, 16, %o1
-; V9-NEXT:    or %o0, %o1, %o0
-; V9-NEXT:    xor %o0, -1, %o0
-; V9-NEXT:    srl %o0, 1, %o1
-; V9-NEXT:    sethi 1398101, %o2
-; V9-NEXT:    or %o2, 341, %o2
-; V9-NEXT:    and %o1, %o2, %o1
-; V9-NEXT:    sub %o0, %o1, %o0
-; V9-NEXT:    sethi 838860, %o1
-; V9-NEXT:    or %o1, 819, %o1
-; V9-NEXT:    and %o0, %o1, %o2
-; V9-NEXT:    srl %o0, 2, %o0
-; V9-NEXT:    and %o0, %o1, %o0
-; V9-NEXT:    add %o2, %o0, %o0
-; V9-NEXT:    srl %o0, 4, %o1
-; V9-NEXT:    add %o0, %o1, %o0
-; V9-NEXT:    sethi 246723, %o1
-; V9-NEXT:    or %o1, 783, %o1
-; V9-NEXT:    and %o0, %o1, %o0
-; V9-NEXT:    sll %o0, 8, %o1
-; V9-NEXT:    add %o0, %o1, %o0
-; V9-NEXT:    sll %o0, 16, %o1
-; V9-NEXT:    add %o0, %o1, %o0
-; V9-NEXT:    retl
-; V9-NEXT:    srl %o0, 24, %o0
+; V9-NEXT:    call __clzdi2
+; V9-NEXT:    sllx %i0, 32, %o0
+; V9-NEXT:    ret
+; V9-NEXT:    restore %g0, %o0, %o0
 ; V9-NEXT:  .LBB0_2:
-; V9-NEXT:    retl
-; V9-NEXT:    mov 32, %o0
+; V9-NEXT:    ret
+; V9-NEXT:    restore %g0, 32, %o0
 ;
 ; POPC-LABEL: i32_nopoison:
 ; POPC:       ! %bb.0:
@@ -90,39 +62,11 @@ define i32 @i32_nopoison(i32 %x) nounwind {
 define i32 @i32_poison(i32 %x) nounwind {
 ; V9-LABEL: i32_poison:
 ; V9:       ! %bb.0:
-; V9-NEXT:    srl %o0, 1, %o1
-; V9-NEXT:    or %o0, %o1, %o0
-; V9-NEXT:    srl %o0, 2, %o1
-; V9-NEXT:    or %o0, %o1, %o0
-; V9-NEXT:    srl %o0, 4, %o1
-; V9-NEXT:    or %o0, %o1, %o0
-; V9-NEXT:    srl %o0, 8, %o1
-; V9-NEXT:    or %o0, %o1, %o0
-; V9-NEXT:    srl %o0, 16, %o1
-; V9-NEXT:    or %o0, %o1, %o0
-; V9-NEXT:    xor %o0, -1, %o0
-; V9-NEXT:    srl %o0, 1, %o1
-; V9-NEXT:    sethi 1398101, %o2
-; V9-NEXT:    or %o2, 341, %o2
-; V9-NEXT:    and %o1, %o2, %o1
-; V9-NEXT:    sub %o0, %o1, %o0
-; V9-NEXT:    sethi 838860, %o1
-; V9-NEXT:    or %o1, 819, %o1
-; V9-NEXT:    and %o0, %o1, %o2
-; V9-NEXT:    srl %o0, 2, %o0
-; V9-NEXT:    and %o0, %o1, %o0
-; V9-NEXT:    add %o2, %o0, %o0
-; V9-NEXT:    srl %o0, 4, %o1
-; V9-NEXT:    add %o0, %o1, %o0
-; V9-NEXT:    sethi 246723, %o1
-; V9-NEXT:    or %o1, 783, %o1
-; V9-NEXT:    and %o0, %o1, %o0
-; V9-NEXT:    sll %o0, 8, %o1
-; V9-NEXT:    add %o0, %o1, %o0
-; V9-NEXT:    sll %o0, 16, %o1
-; V9-NEXT:    add %o0, %o1, %o0
-; V9-NEXT:    retl
-; V9-NEXT:    srl %o0, 24, %o0
+; V9-NEXT:    save %sp, -176, %sp
+; V9-NEXT:    call __clzdi2
+; V9-NEXT:    sllx %i0, 32, %o0
+; V9-NEXT:    ret
+; V9-NEXT:    restore %g0, %o0, %o0
 ;
 ; POPC-LABEL: i32_poison:
 ; POPC:       ! %bb.0:
@@ -153,54 +97,17 @@ define i32 @i32_poison(i32 %x) nounwind {
 define i64 @i64_nopoison(i64 %x) nounwind {
 ; V9-LABEL: i64_nopoison:
 ; V9:       ! %bb.0:
-; V9-NEXT:    brz %o0, .LBB2_2
+; V9-NEXT:    save %sp, -176, %sp
+; V9-NEXT:    brz %i0, .LBB2_2
 ; V9-NEXT:    nop
 ; V9-NEXT:  ! %bb.1: ! %cond.false
-; V9-NEXT:    srlx %o0, 1, %o1
-; V9-NEXT:    or %o0, %o1, %o0
-; V9-NEXT:    srlx %o0, 2, %o1
-; V9-NEXT:    or %o0, %o1, %o0
-; V9-NEXT:    srlx %o0, 4, %o1
-; V9-NEXT:    or %o0, %o1, %o0
-; V9-NEXT:    srlx %o0, 8, %o1
-; V9-NEXT:    or %o0, %o1, %o0
-; V9-NEXT:    srlx %o0, 16, %o1
-; V9-NEXT:    or %o0, %o1, %o0
-; V9-NEXT:    srlx %o0, 32, %o1
-; V9-NEXT:    or %o0, %o1, %o0
-; V9-NEXT:    xor %o0, -1, %o0
-; V9-NEXT:    srlx %o0, 1, %o1
-; V9-NEXT:    sethi 1398101, %o2
-; V9-NEXT:    or %o2, 341, %o2
-; V9-NEXT:    sllx %o2, 32, %o3
-; V9-NEXT:    or %o3, %o2, %o2
-; V9-NEXT:    and %o1, %o2, %o1
-; V9-NEXT:    sub %o0, %o1, %o0
-; V9-NEXT:    sethi 838860, %o1
-; V9-NEXT:    or %o1, 819, %o1
-; V9-NEXT:    sllx %o1, 32, %o2
-; V9-NEXT:    or %o2, %o1, %o1
-; V9-NEXT:    and %o0, %o1, %o2
-; V9-NEXT:    srlx %o0, 2, %o0
-; V9-NEXT:    and %o0, %o1, %o0
-; V9-NEXT:    add %o2, %o0, %o0
-; V9-NEXT:    srlx %o0, 4, %o1
-; V9-NEXT:    add %o0, %o1, %o0
-; V9-NEXT:    sethi 246723, %o1
-; V9-NEXT:    or %o1, 783, %o1
-; V9-NEXT:    sllx %o1, 32, %o2
-; V9-NEXT:    or %o2, %o1, %o1
-; V9-NEXT:    and %o0, %o1, %o0
-; V9-NEXT:    sethi 16448, %o1
-; V9-NEXT:    or %o1, 257, %o1
-; V9-NEXT:    sllx %o1, 32, %o2
-; V9-NEXT:    or %o2, %o1, %o1
-; V9-NEXT:    mulx %o0, %o1, %o0
-; V9-NEXT:    retl
-; V9-NEXT:    srlx %o0, 56, %o0
+; V9-NEXT:    call __clzdi2
+; V9-NEXT:    mov %i0, %o0
+; V9-NEXT:    ret
+; V9-NEXT:    restore %g0, %o0, %o0
 ; V9-NEXT:  .LBB2_2:
-; V9-NEXT:    retl
-; V9-NEXT:    mov 64, %o0
+; V9-NEXT:    ret
+; V9-NEXT:    restore %g0, 64, %o0
 ;
 ; POPC-LABEL: i64_nopoison:
 ; POPC:       ! %bb.0:
@@ -243,48 +150,11 @@ define i64 @i64_nopoison(i64 %x) nounwind {
 define i64 @i64_poison(i64 %x) nounwind {
 ; V9-LABEL: i64_poison:
 ; V9:       ! %bb.0:
-; V9-NEXT:    srlx %o0, 1, %o1
-; V9-NEXT:    or %o0, %o1, %o0
-; V9-NEXT:    srlx %o0, 2, %o1
-; V9-NEXT:    or %o0, %o1, %o0
-; V9-NEXT:    srlx %o0, 4, %o1
-; V9-NEXT:    or %o0, %o1, %o0
-; V9-NEXT:    srlx %o0, 8, %o1
-; V9-NEXT:    or %o0, %o1, %o0
-; V9-NEXT:    srlx %o0, 16, %o1
-; V9-NEXT:    or %o0, %o1, %o0
-; V9-NEXT:    srlx %o0, 32, %o1
-; V9-NEXT:    or %o0, %o1, %o0
-; V9-NEXT:    xor %o0, -1, %o0
-; V9-NEXT:    srlx %o0, 1, %o1
-; V9-NEXT:    sethi 1398101, %o2
-; V9-NEXT:    or %o2, 341, %o2
-; V9-NEXT:    sllx %o2, 32, %o3
-; V9-NEXT:    or %o3, %o2, %o2
-; V9-NEXT:    and %o1, %o2, %o1
-; V9-NEXT:    sub %o0, %o1, %o0
-; V9-NEXT:    sethi 838860, %o1
-; V9-NEXT:    or %o1, 819, %o1
-; V9-NEXT:    sllx %o1, 32, %o2
-; V9-NEXT:    or %o2, %o1, %o1
-; V9-NEXT:    and %o0, %o1, %o2
-; V9-NEXT:    srlx %o0, 2, %o0
-; V9-NEXT:    and %o0, %o1, %o0
-; V9-NEXT:    add %o2, %o0, %o0
-; V9-NEXT:    srlx %o0, 4, %o1
-; V9-NEXT:    add %o0, %o1, %o0
-; V9-NEXT:    sethi 246723, %o1
-; V9-NEXT:    or %o1, 783, %o1
-; V9-NEXT:    sllx %o1, 32, %o2
-; V9-NEXT:    or %o2, %o1, %o1
-; V9-NEXT:    and %o0, %o1, %o0
-; V9-NEXT:    sethi 16448, %o1
-; V9-NEXT:    or %o1, 257, %o1
-; V9-NEXT:    sllx %o1, 32, %o2
-; V9-NEXT:    or %o2, %o1, %o1
-; V9-NEXT:    mulx %o0, %o1, %o0
-; V9-NEXT:    retl
-; V9-NEXT:    srlx %o0, 56, %o0
+; V9-NEXT:    save %sp, -176, %sp
+; V9-NEXT:    call __clzdi2
+; V9-NEXT:    mov %i0, %o0
+; V9-NEXT:    ret
+; V9-NEXT:    restore %g0, %o0, %o0
 ;
 ; POPC-LABEL: i64_poison:
 ; POPC:       ! %bb.0:

>From c196033fc74c0e2aec54ec6a3cf07a15a9208ccc Mon Sep 17 00:00:00 2001
From: Koakuma <koachan at protonmail.com>
Date: Thu, 17 Apr 2025 09:11:17 +0700
Subject: [PATCH 2/4] Add back i32 pattern since the instruction is also usable
 in 32-bit mode

Created using spr 1.3.5
---
 llvm/lib/Target/Sparc/SparcISelLowering.cpp |  16 +-
 llvm/lib/Target/Sparc/SparcInstrVIS.td      |   7 +
 llvm/test/CodeGen/SPARC/ctlz.ll             | 566 ++++++++++++++------
 3 files changed, 420 insertions(+), 169 deletions(-)

diff --git a/llvm/lib/Target/Sparc/SparcISelLowering.cpp b/llvm/lib/Target/Sparc/SparcISelLowering.cpp
index e455706b0528f..386a9bd72c965 100644
--- a/llvm/lib/Target/Sparc/SparcISelLowering.cpp
+++ b/llvm/lib/Target/Sparc/SparcISelLowering.cpp
@@ -1753,9 +1753,7 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM,
 
     setOperationAction(ISD::CTPOP, MVT::i64,
                        Subtarget->usePopc() ? Legal : Expand);
-    setOperationAction(ISD::CTTZ , MVT::i64, Expand);
-    setOperationAction(ISD::CTLZ, MVT::i64,
-                       Subtarget->isVIS3() ? Legal : Expand);
+    setOperationAction(ISD::CTTZ, MVT::i64, Expand);
     setOperationAction(ISD::BSWAP, MVT::i64, Expand);
     setOperationAction(ISD::ROTL , MVT::i64, Expand);
     setOperationAction(ISD::ROTR , MVT::i64, Expand);
@@ -1816,9 +1814,7 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM,
   setOperationAction(ISD::FSINCOS, MVT::f32, Expand);
   setOperationAction(ISD::FREM , MVT::f32, Expand);
   setOperationAction(ISD::FMA  , MVT::f32, Expand);
-  setOperationAction(ISD::CTTZ , MVT::i32, Expand);
-  setOperationAction(ISD::CTLZ, MVT::i32,
-                     Subtarget->isVIS3() ? Promote : Expand);
+  setOperationAction(ISD::CTTZ, MVT::i32, Expand);
   setOperationAction(ISD::ROTL , MVT::i32, Expand);
   setOperationAction(ISD::ROTR , MVT::i32, Expand);
   setOperationAction(ISD::BSWAP, MVT::i32, Expand);
@@ -1990,12 +1986,18 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM,
     setOperationAction(ISD::READCYCLECOUNTER, MVT::i64, Custom);
 
   if (Subtarget->isVIS3()) {
-    setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i32, Promote);
+    setOperationAction(ISD::CTLZ, MVT::i32, Legal);
+    setOperationAction(ISD::CTLZ, MVT::i64, Legal);
+    setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i32, Legal);
     setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i64, Legal);
   } else if (Subtarget->usePopc()) {
+    setOperationAction(ISD::CTLZ, MVT::i32, Expand);
+    setOperationAction(ISD::CTLZ, MVT::i64, Expand);
     setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i32, Expand);
     setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i64, Expand);
   } else {
+    setOperationAction(ISD::CTLZ, MVT::i32, Expand);
+    setOperationAction(ISD::CTLZ, MVT::i64, Expand);
     setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i32,
                        Subtarget->is64Bit() ? Promote : LibCall);
     setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i64, LibCall);
diff --git a/llvm/lib/Target/Sparc/SparcInstrVIS.td b/llvm/lib/Target/Sparc/SparcInstrVIS.td
index b26349952fd5d..78f50888b5508 100644
--- a/llvm/lib/Target/Sparc/SparcInstrVIS.td
+++ b/llvm/lib/Target/Sparc/SparcInstrVIS.td
@@ -297,4 +297,11 @@ def : Pat<(i64 (adde i64:$lhs, i64:$rhs)), (ADDXCCC $lhs, $rhs)>;
 
 def : Pat<(i64 (ctlz i64:$src)), (LZCNT $src)>;
 def : Pat<(i64 (ctlz_zero_undef i64:$src)), (LZCNT $src)>;
+// 32-bit LZCNT.
+// The zero extension will leave us with 32 extra leading zeros,
+// so we need to compensate for it.
+// FIXME remove this when the codegen supports using 64-bit values directly
+// in V8+ mode.
+def : Pat<(i32 (ctlz i32:$src)), (ADDri (LZCNT (SRLri $src, 0)), (i32 -32))>;
+def : Pat<(i32 (ctlz_zero_undef i32:$src)), (ADDri (LZCNT (SRLri $src, 0)), (i32 -32))>;
 } // Predicates = [HasVIS3]
diff --git a/llvm/test/CodeGen/SPARC/ctlz.ll b/llvm/test/CodeGen/SPARC/ctlz.ll
index 3391af02e4bc0..f3563c769f7f6 100644
--- a/llvm/test/CodeGen/SPARC/ctlz.ll
+++ b/llvm/test/CodeGen/SPARC/ctlz.ll
@@ -1,183 +1,425 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-; RUN: llc < %s -mtriple=sparcv9 | FileCheck %s -check-prefix=V9
-; RUN: llc < %s -mtriple=sparcv9 -mattr=popc | FileCheck %s -check-prefix=POPC
-; RUN: llc < %s -mtriple=sparcv9 -mattr=vis3 | FileCheck %s -check-prefix=VIS3
+; RUN: llc < %s -mtriple=sparc | FileCheck %s -check-prefix=SPARC
+; RUN: llc < %s -mtriple=sparc -mattr=popc | FileCheck %s -check-prefix=SPARC-POPC
+; RUN: llc < %s -mtriple=sparc -mattr=vis3 | FileCheck %s -check-prefix=SPARC-VIS3
+; RUN: llc < %s -mtriple=sparcv9 | FileCheck %s -check-prefix=SPARC64
+; RUN: llc < %s -mtriple=sparcv9 -mattr=popc | FileCheck %s -check-prefix=SPARC64-POPC
+; RUN: llc < %s -mtriple=sparcv9 -mattr=vis3 | FileCheck %s -check-prefix=SPARC64-VIS3
 
 define i32 @i32_nopoison(i32 %x) nounwind {
-; V9-LABEL: i32_nopoison:
-; V9:       ! %bb.0:
-; V9-NEXT:    save %sp, -176, %sp
-; V9-NEXT:    cmp %i0, 0
-; V9-NEXT:    be %icc, .LBB0_2
-; V9-NEXT:    nop
-; V9-NEXT:  ! %bb.1: ! %cond.false
-; V9-NEXT:    call __clzdi2
-; V9-NEXT:    sllx %i0, 32, %o0
-; V9-NEXT:    ret
-; V9-NEXT:    restore %g0, %o0, %o0
-; V9-NEXT:  .LBB0_2:
-; V9-NEXT:    ret
-; V9-NEXT:    restore %g0, 32, %o0
-;
-; POPC-LABEL: i32_nopoison:
-; POPC:       ! %bb.0:
-; POPC-NEXT:    cmp %o0, 0
-; POPC-NEXT:    be %icc, .LBB0_2
-; POPC-NEXT:    nop
-; POPC-NEXT:  ! %bb.1: ! %cond.false
-; POPC-NEXT:    srl %o0, 1, %o1
-; POPC-NEXT:    or %o0, %o1, %o0
-; POPC-NEXT:    srl %o0, 2, %o1
-; POPC-NEXT:    or %o0, %o1, %o0
-; POPC-NEXT:    srl %o0, 4, %o1
-; POPC-NEXT:    or %o0, %o1, %o0
-; POPC-NEXT:    srl %o0, 8, %o1
-; POPC-NEXT:    or %o0, %o1, %o0
-; POPC-NEXT:    srl %o0, 16, %o1
-; POPC-NEXT:    or %o0, %o1, %o0
-; POPC-NEXT:    xor %o0, -1, %o0
-; POPC-NEXT:    srl %o0, 0, %o0
-; POPC-NEXT:    retl
-; POPC-NEXT:    popc %o0, %o0
-; POPC-NEXT:  .LBB0_2:
-; POPC-NEXT:    retl
-; POPC-NEXT:    mov 32, %o0
-;
-; VIS3-LABEL: i32_nopoison:
-; VIS3:       ! %bb.0:
-; VIS3-NEXT:    cmp %o0, 0
-; VIS3-NEXT:    be %icc, .LBB0_2
-; VIS3-NEXT:    nop
-; VIS3-NEXT:  ! %bb.1: ! %cond.false
-; VIS3-NEXT:    sllx %o0, 32, %o0
-; VIS3-NEXT:    retl
-; VIS3-NEXT:    lzcnt %o0, %o0
-; VIS3-NEXT:  .LBB0_2:
-; VIS3-NEXT:    retl
-; VIS3-NEXT:    mov 32, %o0
+; SPARC-LABEL: i32_nopoison:
+; SPARC:       ! %bb.0:
+; SPARC-NEXT:    save %sp, -96, %sp
+; SPARC-NEXT:    cmp %i0, 0
+; SPARC-NEXT:    be .LBB0_2
+; SPARC-NEXT:    nop
+; SPARC-NEXT:  ! %bb.1: ! %cond.false
+; SPARC-NEXT:    call __clzsi2
+; SPARC-NEXT:    mov %i0, %o0
+; SPARC-NEXT:    ret
+; SPARC-NEXT:    restore %g0, %o0, %o0
+; SPARC-NEXT:  .LBB0_2:
+; SPARC-NEXT:    ret
+; SPARC-NEXT:    restore %g0, 32, %o0
+;
+; SPARC-POPC-LABEL: i32_nopoison:
+; SPARC-POPC:       ! %bb.0:
+; SPARC-POPC-NEXT:    save %sp, -96, %sp
+; SPARC-POPC-NEXT:    cmp %i0, 0
+; SPARC-POPC-NEXT:    be .LBB0_2
+; SPARC-POPC-NEXT:    nop
+; SPARC-POPC-NEXT:  ! %bb.1: ! %cond.false
+; SPARC-POPC-NEXT:    call __clzsi2
+; SPARC-POPC-NEXT:    mov %i0, %o0
+; SPARC-POPC-NEXT:    ret
+; SPARC-POPC-NEXT:    restore %g0, %o0, %o0
+; SPARC-POPC-NEXT:  .LBB0_2:
+; SPARC-POPC-NEXT:    ret
+; SPARC-POPC-NEXT:    restore %g0, 32, %o0
+;
+; SPARC-VIS3-LABEL: i32_nopoison:
+; SPARC-VIS3:       ! %bb.0:
+; SPARC-VIS3-NEXT:    cmp %o0, 0
+; SPARC-VIS3-NEXT:    be .LBB0_2
+; SPARC-VIS3-NEXT:    nop
+; SPARC-VIS3-NEXT:  ! %bb.1: ! %cond.false
+; SPARC-VIS3-NEXT:    srl %o0, 0, %o0
+; SPARC-VIS3-NEXT:    lzcnt %o0, %o0
+; SPARC-VIS3-NEXT:    retl
+; SPARC-VIS3-NEXT:    add %o0, -32, %o0
+; SPARC-VIS3-NEXT:  .LBB0_2:
+; SPARC-VIS3-NEXT:    retl
+; SPARC-VIS3-NEXT:    mov 32, %o0
+;
+; SPARC64-LABEL: i32_nopoison:
+; SPARC64:       ! %bb.0:
+; SPARC64-NEXT:    save %sp, -176, %sp
+; SPARC64-NEXT:    cmp %i0, 0
+; SPARC64-NEXT:    be %icc, .LBB0_2
+; SPARC64-NEXT:    nop
+; SPARC64-NEXT:  ! %bb.1: ! %cond.false
+; SPARC64-NEXT:    call __clzdi2
+; SPARC64-NEXT:    sllx %i0, 32, %o0
+; SPARC64-NEXT:    ret
+; SPARC64-NEXT:    restore %g0, %o0, %o0
+; SPARC64-NEXT:  .LBB0_2:
+; SPARC64-NEXT:    ret
+; SPARC64-NEXT:    restore %g0, 32, %o0
+;
+; SPARC64-POPC-LABEL: i32_nopoison:
+; SPARC64-POPC:       ! %bb.0:
+; SPARC64-POPC-NEXT:    cmp %o0, 0
+; SPARC64-POPC-NEXT:    be %icc, .LBB0_2
+; SPARC64-POPC-NEXT:    nop
+; SPARC64-POPC-NEXT:  ! %bb.1: ! %cond.false
+; SPARC64-POPC-NEXT:    srl %o0, 1, %o1
+; SPARC64-POPC-NEXT:    or %o0, %o1, %o0
+; SPARC64-POPC-NEXT:    srl %o0, 2, %o1
+; SPARC64-POPC-NEXT:    or %o0, %o1, %o0
+; SPARC64-POPC-NEXT:    srl %o0, 4, %o1
+; SPARC64-POPC-NEXT:    or %o0, %o1, %o0
+; SPARC64-POPC-NEXT:    srl %o0, 8, %o1
+; SPARC64-POPC-NEXT:    or %o0, %o1, %o0
+; SPARC64-POPC-NEXT:    srl %o0, 16, %o1
+; SPARC64-POPC-NEXT:    or %o0, %o1, %o0
+; SPARC64-POPC-NEXT:    xor %o0, -1, %o0
+; SPARC64-POPC-NEXT:    srl %o0, 0, %o0
+; SPARC64-POPC-NEXT:    retl
+; SPARC64-POPC-NEXT:    popc %o0, %o0
+; SPARC64-POPC-NEXT:  .LBB0_2:
+; SPARC64-POPC-NEXT:    retl
+; SPARC64-POPC-NEXT:    mov 32, %o0
+;
+; SPARC64-VIS3-LABEL: i32_nopoison:
+; SPARC64-VIS3:       ! %bb.0:
+; SPARC64-VIS3-NEXT:    cmp %o0, 0
+; SPARC64-VIS3-NEXT:    be %icc, .LBB0_2
+; SPARC64-VIS3-NEXT:    nop
+; SPARC64-VIS3-NEXT:  ! %bb.1: ! %cond.false
+; SPARC64-VIS3-NEXT:    srl %o0, 0, %o0
+; SPARC64-VIS3-NEXT:    lzcnt %o0, %o0
+; SPARC64-VIS3-NEXT:    retl
+; SPARC64-VIS3-NEXT:    add %o0, -32, %o0
+; SPARC64-VIS3-NEXT:  .LBB0_2:
+; SPARC64-VIS3-NEXT:    retl
+; SPARC64-VIS3-NEXT:    mov 32, %o0
   %ret = call i32 @llvm.ctlz.i32(i32 %x, i1 false)
   ret i32 %ret
 }
 
 define i32 @i32_poison(i32 %x) nounwind {
-; V9-LABEL: i32_poison:
-; V9:       ! %bb.0:
-; V9-NEXT:    save %sp, -176, %sp
-; V9-NEXT:    call __clzdi2
-; V9-NEXT:    sllx %i0, 32, %o0
-; V9-NEXT:    ret
-; V9-NEXT:    restore %g0, %o0, %o0
-;
-; POPC-LABEL: i32_poison:
-; POPC:       ! %bb.0:
-; POPC-NEXT:    srl %o0, 1, %o1
-; POPC-NEXT:    or %o0, %o1, %o0
-; POPC-NEXT:    srl %o0, 2, %o1
-; POPC-NEXT:    or %o0, %o1, %o0
-; POPC-NEXT:    srl %o0, 4, %o1
-; POPC-NEXT:    or %o0, %o1, %o0
-; POPC-NEXT:    srl %o0, 8, %o1
-; POPC-NEXT:    or %o0, %o1, %o0
-; POPC-NEXT:    srl %o0, 16, %o1
-; POPC-NEXT:    or %o0, %o1, %o0
-; POPC-NEXT:    xor %o0, -1, %o0
-; POPC-NEXT:    srl %o0, 0, %o0
-; POPC-NEXT:    retl
-; POPC-NEXT:    popc %o0, %o0
-;
-; VIS3-LABEL: i32_poison:
-; VIS3:       ! %bb.0:
-; VIS3-NEXT:    sllx %o0, 32, %o0
-; VIS3-NEXT:    retl
-; VIS3-NEXT:    lzcnt %o0, %o0
+; SPARC-LABEL: i32_poison:
+; SPARC:       ! %bb.0:
+; SPARC-NEXT:    save %sp, -96, %sp
+; SPARC-NEXT:    call __clzsi2
+; SPARC-NEXT:    mov %i0, %o0
+; SPARC-NEXT:    ret
+; SPARC-NEXT:    restore %g0, %o0, %o0
+;
+; SPARC-POPC-LABEL: i32_poison:
+; SPARC-POPC:       ! %bb.0:
+; SPARC-POPC-NEXT:    save %sp, -96, %sp
+; SPARC-POPC-NEXT:    call __clzsi2
+; SPARC-POPC-NEXT:    mov %i0, %o0
+; SPARC-POPC-NEXT:    ret
+; SPARC-POPC-NEXT:    restore %g0, %o0, %o0
+;
+; SPARC-VIS3-LABEL: i32_poison:
+; SPARC-VIS3:       ! %bb.0:
+; SPARC-VIS3-NEXT:    srl %o0, 0, %o0
+; SPARC-VIS3-NEXT:    lzcnt %o0, %o0
+; SPARC-VIS3-NEXT:    retl
+; SPARC-VIS3-NEXT:    add %o0, -32, %o0
+;
+; SPARC64-LABEL: i32_poison:
+; SPARC64:       ! %bb.0:
+; SPARC64-NEXT:    save %sp, -176, %sp
+; SPARC64-NEXT:    call __clzdi2
+; SPARC64-NEXT:    sllx %i0, 32, %o0
+; SPARC64-NEXT:    ret
+; SPARC64-NEXT:    restore %g0, %o0, %o0
+;
+; SPARC64-POPC-LABEL: i32_poison:
+; SPARC64-POPC:       ! %bb.0:
+; SPARC64-POPC-NEXT:    srl %o0, 1, %o1
+; SPARC64-POPC-NEXT:    or %o0, %o1, %o0
+; SPARC64-POPC-NEXT:    srl %o0, 2, %o1
+; SPARC64-POPC-NEXT:    or %o0, %o1, %o0
+; SPARC64-POPC-NEXT:    srl %o0, 4, %o1
+; SPARC64-POPC-NEXT:    or %o0, %o1, %o0
+; SPARC64-POPC-NEXT:    srl %o0, 8, %o1
+; SPARC64-POPC-NEXT:    or %o0, %o1, %o0
+; SPARC64-POPC-NEXT:    srl %o0, 16, %o1
+; SPARC64-POPC-NEXT:    or %o0, %o1, %o0
+; SPARC64-POPC-NEXT:    xor %o0, -1, %o0
+; SPARC64-POPC-NEXT:    srl %o0, 0, %o0
+; SPARC64-POPC-NEXT:    retl
+; SPARC64-POPC-NEXT:    popc %o0, %o0
+;
+; SPARC64-VIS3-LABEL: i32_poison:
+; SPARC64-VIS3:       ! %bb.0:
+; SPARC64-VIS3-NEXT:    srl %o0, 0, %o0
+; SPARC64-VIS3-NEXT:    lzcnt %o0, %o0
+; SPARC64-VIS3-NEXT:    retl
+; SPARC64-VIS3-NEXT:    add %o0, -32, %o0
   %ret = call i32 @llvm.ctlz.i32(i32 %x, i1 true)
   ret i32 %ret
 }
 
 define i64 @i64_nopoison(i64 %x) nounwind {
-; V9-LABEL: i64_nopoison:
-; V9:       ! %bb.0:
-; V9-NEXT:    save %sp, -176, %sp
-; V9-NEXT:    brz %i0, .LBB2_2
-; V9-NEXT:    nop
-; V9-NEXT:  ! %bb.1: ! %cond.false
-; V9-NEXT:    call __clzdi2
-; V9-NEXT:    mov %i0, %o0
-; V9-NEXT:    ret
-; V9-NEXT:    restore %g0, %o0, %o0
-; V9-NEXT:  .LBB2_2:
-; V9-NEXT:    ret
-; V9-NEXT:    restore %g0, 64, %o0
-;
-; POPC-LABEL: i64_nopoison:
-; POPC:       ! %bb.0:
-; POPC-NEXT:    brz %o0, .LBB2_2
-; POPC-NEXT:    nop
-; POPC-NEXT:  ! %bb.1: ! %cond.false
-; POPC-NEXT:    srlx %o0, 1, %o1
-; POPC-NEXT:    or %o0, %o1, %o0
-; POPC-NEXT:    srlx %o0, 2, %o1
-; POPC-NEXT:    or %o0, %o1, %o0
-; POPC-NEXT:    srlx %o0, 4, %o1
-; POPC-NEXT:    or %o0, %o1, %o0
-; POPC-NEXT:    srlx %o0, 8, %o1
-; POPC-NEXT:    or %o0, %o1, %o0
-; POPC-NEXT:    srlx %o0, 16, %o1
-; POPC-NEXT:    or %o0, %o1, %o0
-; POPC-NEXT:    srlx %o0, 32, %o1
-; POPC-NEXT:    or %o0, %o1, %o0
-; POPC-NEXT:    xor %o0, -1, %o0
-; POPC-NEXT:    retl
-; POPC-NEXT:    popc %o0, %o0
-; POPC-NEXT:  .LBB2_2:
-; POPC-NEXT:    retl
-; POPC-NEXT:    mov 64, %o0
-;
-; VIS3-LABEL: i64_nopoison:
-; VIS3:       ! %bb.0:
-; VIS3-NEXT:    brz %o0, .LBB2_2
-; VIS3-NEXT:    nop
-; VIS3-NEXT:  ! %bb.1: ! %cond.false
-; VIS3-NEXT:    retl
-; VIS3-NEXT:    lzcnt %o0, %o0
-; VIS3-NEXT:  .LBB2_2:
-; VIS3-NEXT:    retl
-; VIS3-NEXT:    mov 64, %o0
+; SPARC-LABEL: i64_nopoison:
+; SPARC:       ! %bb.0:
+; SPARC-NEXT:    save %sp, -96, %sp
+; SPARC-NEXT:    call __clzsi2
+; SPARC-NEXT:    mov %i0, %o0
+; SPARC-NEXT:    cmp %i0, 0
+; SPARC-NEXT:    bne .LBB2_2
+; SPARC-NEXT:    nop
+; SPARC-NEXT:  ! %bb.1:
+; SPARC-NEXT:    srl %i1, 1, %i0
+; SPARC-NEXT:    or %i1, %i0, %i0
+; SPARC-NEXT:    srl %i0, 2, %i1
+; SPARC-NEXT:    or %i0, %i1, %i0
+; SPARC-NEXT:    srl %i0, 4, %i1
+; SPARC-NEXT:    or %i0, %i1, %i0
+; SPARC-NEXT:    srl %i0, 8, %i1
+; SPARC-NEXT:    or %i0, %i1, %i0
+; SPARC-NEXT:    srl %i0, 16, %i1
+; SPARC-NEXT:    or %i0, %i1, %i0
+; SPARC-NEXT:    xor %i0, -1, %i0
+; SPARC-NEXT:    srl %i0, 1, %i1
+; SPARC-NEXT:    sethi 1398101, %i2
+; SPARC-NEXT:    or %i2, 341, %i2
+; SPARC-NEXT:    and %i1, %i2, %i1
+; SPARC-NEXT:    sub %i0, %i1, %i0
+; SPARC-NEXT:    sethi 838860, %i1
+; SPARC-NEXT:    or %i1, 819, %i1
+; SPARC-NEXT:    and %i0, %i1, %i2
+; SPARC-NEXT:    srl %i0, 2, %i0
+; SPARC-NEXT:    and %i0, %i1, %i0
+; SPARC-NEXT:    add %i2, %i0, %i0
+; SPARC-NEXT:    srl %i0, 4, %i1
+; SPARC-NEXT:    add %i0, %i1, %i0
+; SPARC-NEXT:    sethi 246723, %i1
+; SPARC-NEXT:    or %i1, 783, %i1
+; SPARC-NEXT:    and %i0, %i1, %i0
+; SPARC-NEXT:    sll %i0, 8, %i1
+; SPARC-NEXT:    add %i0, %i1, %i0
+; SPARC-NEXT:    sll %i0, 16, %i1
+; SPARC-NEXT:    add %i0, %i1, %i0
+; SPARC-NEXT:    srl %i0, 24, %i0
+; SPARC-NEXT:    add %i0, 32, %o0
+; SPARC-NEXT:  .LBB2_2:
+; SPARC-NEXT:    mov %g0, %i0
+; SPARC-NEXT:    ret
+; SPARC-NEXT:    restore %g0, %o0, %o1
+;
+; SPARC-POPC-LABEL: i64_nopoison:
+; SPARC-POPC:       ! %bb.0:
+; SPARC-POPC-NEXT:    save %sp, -96, %sp
+; SPARC-POPC-NEXT:    call __clzsi2
+; SPARC-POPC-NEXT:    mov %i0, %o0
+; SPARC-POPC-NEXT:    cmp %i0, 0
+; SPARC-POPC-NEXT:    bne .LBB2_2
+; SPARC-POPC-NEXT:    nop
+; SPARC-POPC-NEXT:  ! %bb.1:
+; SPARC-POPC-NEXT:    srl %i1, 1, %i0
+; SPARC-POPC-NEXT:    or %i1, %i0, %i0
+; SPARC-POPC-NEXT:    srl %i0, 2, %i1
+; SPARC-POPC-NEXT:    or %i0, %i1, %i0
+; SPARC-POPC-NEXT:    srl %i0, 4, %i1
+; SPARC-POPC-NEXT:    or %i0, %i1, %i0
+; SPARC-POPC-NEXT:    srl %i0, 8, %i1
+; SPARC-POPC-NEXT:    or %i0, %i1, %i0
+; SPARC-POPC-NEXT:    srl %i0, 16, %i1
+; SPARC-POPC-NEXT:    or %i0, %i1, %i0
+; SPARC-POPC-NEXT:    xor %i0, -1, %i0
+; SPARC-POPC-NEXT:    srl %i0, 1, %i1
+; SPARC-POPC-NEXT:    sethi 1398101, %i2
+; SPARC-POPC-NEXT:    or %i2, 341, %i2
+; SPARC-POPC-NEXT:    and %i1, %i2, %i1
+; SPARC-POPC-NEXT:    sub %i0, %i1, %i0
+; SPARC-POPC-NEXT:    sethi 838860, %i1
+; SPARC-POPC-NEXT:    or %i1, 819, %i1
+; SPARC-POPC-NEXT:    and %i0, %i1, %i2
+; SPARC-POPC-NEXT:    srl %i0, 2, %i0
+; SPARC-POPC-NEXT:    and %i0, %i1, %i0
+; SPARC-POPC-NEXT:    add %i2, %i0, %i0
+; SPARC-POPC-NEXT:    srl %i0, 4, %i1
+; SPARC-POPC-NEXT:    add %i0, %i1, %i0
+; SPARC-POPC-NEXT:    sethi 246723, %i1
+; SPARC-POPC-NEXT:    or %i1, 783, %i1
+; SPARC-POPC-NEXT:    and %i0, %i1, %i0
+; SPARC-POPC-NEXT:    sll %i0, 8, %i1
+; SPARC-POPC-NEXT:    add %i0, %i1, %i0
+; SPARC-POPC-NEXT:    sll %i0, 16, %i1
+; SPARC-POPC-NEXT:    add %i0, %i1, %i0
+; SPARC-POPC-NEXT:    srl %i0, 24, %i0
+; SPARC-POPC-NEXT:    add %i0, 32, %o0
+; SPARC-POPC-NEXT:  .LBB2_2:
+; SPARC-POPC-NEXT:    mov %g0, %i0
+; SPARC-POPC-NEXT:    ret
+; SPARC-POPC-NEXT:    restore %g0, %o0, %o1
+;
+; SPARC-VIS3-LABEL: i64_nopoison:
+; SPARC-VIS3:       ! %bb.0:
+; SPARC-VIS3-NEXT:    cmp %o0, 0
+; SPARC-VIS3-NEXT:    bne .LBB2_2
+; SPARC-VIS3-NEXT:    nop
+; SPARC-VIS3-NEXT:  ! %bb.1:
+; SPARC-VIS3-NEXT:    srl %o1, 0, %o0
+; SPARC-VIS3-NEXT:    lzcnt %o0, %o0
+; SPARC-VIS3-NEXT:    add %o0, -32, %o0
+; SPARC-VIS3-NEXT:    add %o0, 32, %o1
+; SPARC-VIS3-NEXT:    retl
+; SPARC-VIS3-NEXT:    mov %g0, %o0
+; SPARC-VIS3-NEXT:  .LBB2_2:
+; SPARC-VIS3-NEXT:    srl %o0, 0, %o0
+; SPARC-VIS3-NEXT:    lzcnt %o0, %o0
+; SPARC-VIS3-NEXT:    add %o0, -32, %o1
+; SPARC-VIS3-NEXT:    retl
+; SPARC-VIS3-NEXT:    mov %g0, %o0
+;
+; SPARC64-LABEL: i64_nopoison:
+; SPARC64:       ! %bb.0:
+; SPARC64-NEXT:    save %sp, -176, %sp
+; SPARC64-NEXT:    brz %i0, .LBB2_2
+; SPARC64-NEXT:    nop
+; SPARC64-NEXT:  ! %bb.1: ! %cond.false
+; SPARC64-NEXT:    call __clzdi2
+; SPARC64-NEXT:    mov %i0, %o0
+; SPARC64-NEXT:    ret
+; SPARC64-NEXT:    restore %g0, %o0, %o0
+; SPARC64-NEXT:  .LBB2_2:
+; SPARC64-NEXT:    ret
+; SPARC64-NEXT:    restore %g0, 64, %o0
+;
+; SPARC64-POPC-LABEL: i64_nopoison:
+; SPARC64-POPC:       ! %bb.0:
+; SPARC64-POPC-NEXT:    brz %o0, .LBB2_2
+; SPARC64-POPC-NEXT:    nop
+; SPARC64-POPC-NEXT:  ! %bb.1: ! %cond.false
+; SPARC64-POPC-NEXT:    srlx %o0, 1, %o1
+; SPARC64-POPC-NEXT:    or %o0, %o1, %o0
+; SPARC64-POPC-NEXT:    srlx %o0, 2, %o1
+; SPARC64-POPC-NEXT:    or %o0, %o1, %o0
+; SPARC64-POPC-NEXT:    srlx %o0, 4, %o1
+; SPARC64-POPC-NEXT:    or %o0, %o1, %o0
+; SPARC64-POPC-NEXT:    srlx %o0, 8, %o1
+; SPARC64-POPC-NEXT:    or %o0, %o1, %o0
+; SPARC64-POPC-NEXT:    srlx %o0, 16, %o1
+; SPARC64-POPC-NEXT:    or %o0, %o1, %o0
+; SPARC64-POPC-NEXT:    srlx %o0, 32, %o1
+; SPARC64-POPC-NEXT:    or %o0, %o1, %o0
+; SPARC64-POPC-NEXT:    xor %o0, -1, %o0
+; SPARC64-POPC-NEXT:    retl
+; SPARC64-POPC-NEXT:    popc %o0, %o0
+; SPARC64-POPC-NEXT:  .LBB2_2:
+; SPARC64-POPC-NEXT:    retl
+; SPARC64-POPC-NEXT:    mov 64, %o0
+;
+; SPARC64-VIS3-LABEL: i64_nopoison:
+; SPARC64-VIS3:       ! %bb.0:
+; SPARC64-VIS3-NEXT:    brz %o0, .LBB2_2
+; SPARC64-VIS3-NEXT:    nop
+; SPARC64-VIS3-NEXT:  ! %bb.1: ! %cond.false
+; SPARC64-VIS3-NEXT:    retl
+; SPARC64-VIS3-NEXT:    lzcnt %o0, %o0
+; SPARC64-VIS3-NEXT:  .LBB2_2:
+; SPARC64-VIS3-NEXT:    retl
+; SPARC64-VIS3-NEXT:    mov 64, %o0
   %ret = call i64 @llvm.ctlz.i64(i64 %x, i1 false)
   ret i64 %ret
 }
 
 define i64 @i64_poison(i64 %x) nounwind {
-; V9-LABEL: i64_poison:
-; V9:       ! %bb.0:
-; V9-NEXT:    save %sp, -176, %sp
-; V9-NEXT:    call __clzdi2
-; V9-NEXT:    mov %i0, %o0
-; V9-NEXT:    ret
-; V9-NEXT:    restore %g0, %o0, %o0
-;
-; POPC-LABEL: i64_poison:
-; POPC:       ! %bb.0:
-; POPC-NEXT:    srlx %o0, 1, %o1
-; POPC-NEXT:    or %o0, %o1, %o0
-; POPC-NEXT:    srlx %o0, 2, %o1
-; POPC-NEXT:    or %o0, %o1, %o0
-; POPC-NEXT:    srlx %o0, 4, %o1
-; POPC-NEXT:    or %o0, %o1, %o0
-; POPC-NEXT:    srlx %o0, 8, %o1
-; POPC-NEXT:    or %o0, %o1, %o0
-; POPC-NEXT:    srlx %o0, 16, %o1
-; POPC-NEXT:    or %o0, %o1, %o0
-; POPC-NEXT:    srlx %o0, 32, %o1
-; POPC-NEXT:    or %o0, %o1, %o0
-; POPC-NEXT:    xor %o0, -1, %o0
-; POPC-NEXT:    retl
-; POPC-NEXT:    popc %o0, %o0
-;
-; VIS3-LABEL: i64_poison:
-; VIS3:       ! %bb.0:
-; VIS3-NEXT:    retl
-; VIS3-NEXT:    lzcnt %o0, %o0
+; SPARC-LABEL: i64_poison:
+; SPARC:       ! %bb.0:
+; SPARC-NEXT:    save %sp, -96, %sp
+; SPARC-NEXT:    mov %i1, %o0
+; SPARC-NEXT:    call __clzsi2
+; SPARC-NEXT:    mov %i0, %i1
+; SPARC-NEXT:    mov %o0, %i0
+; SPARC-NEXT:    call __clzsi2
+; SPARC-NEXT:    mov %i1, %o0
+; SPARC-NEXT:    cmp %i1, 0
+; SPARC-NEXT:    bne .LBB3_2
+; SPARC-NEXT:    nop
+; SPARC-NEXT:  ! %bb.1:
+; SPARC-NEXT:    add %i0, 32, %o0
+; SPARC-NEXT:  .LBB3_2:
+; SPARC-NEXT:    mov %g0, %i0
+; SPARC-NEXT:    ret
+; SPARC-NEXT:    restore %g0, %o0, %o1
+;
+; SPARC-POPC-LABEL: i64_poison:
+; SPARC-POPC:       ! %bb.0:
+; SPARC-POPC-NEXT:    save %sp, -96, %sp
+; SPARC-POPC-NEXT:    mov %i1, %o0
+; SPARC-POPC-NEXT:    call __clzsi2
+; SPARC-POPC-NEXT:    mov %i0, %i1
+; SPARC-POPC-NEXT:    mov %o0, %i0
+; SPARC-POPC-NEXT:    call __clzsi2
+; SPARC-POPC-NEXT:    mov %i1, %o0
+; SPARC-POPC-NEXT:    cmp %i1, 0
+; SPARC-POPC-NEXT:    bne .LBB3_2
+; SPARC-POPC-NEXT:    nop
+; SPARC-POPC-NEXT:  ! %bb.1:
+; SPARC-POPC-NEXT:    add %i0, 32, %o0
+; SPARC-POPC-NEXT:  .LBB3_2:
+; SPARC-POPC-NEXT:    mov %g0, %i0
+; SPARC-POPC-NEXT:    ret
+; SPARC-POPC-NEXT:    restore %g0, %o0, %o1
+;
+; SPARC-VIS3-LABEL: i64_poison:
+; SPARC-VIS3:       ! %bb.0:
+; SPARC-VIS3-NEXT:    cmp %o0, 0
+; SPARC-VIS3-NEXT:    bne .LBB3_2
+; SPARC-VIS3-NEXT:    nop
+; SPARC-VIS3-NEXT:  ! %bb.1:
+; SPARC-VIS3-NEXT:    srl %o1, 0, %o0
+; SPARC-VIS3-NEXT:    lzcnt %o0, %o0
+; SPARC-VIS3-NEXT:    add %o0, -32, %o0
+; SPARC-VIS3-NEXT:    add %o0, 32, %o1
+; SPARC-VIS3-NEXT:    retl
+; SPARC-VIS3-NEXT:    mov %g0, %o0
+; SPARC-VIS3-NEXT:  .LBB3_2:
+; SPARC-VIS3-NEXT:    srl %o0, 0, %o0
+; SPARC-VIS3-NEXT:    lzcnt %o0, %o0
+; SPARC-VIS3-NEXT:    add %o0, -32, %o1
+; SPARC-VIS3-NEXT:    retl
+; SPARC-VIS3-NEXT:    mov %g0, %o0
+;
+; SPARC64-LABEL: i64_poison:
+; SPARC64:       ! %bb.0:
+; SPARC64-NEXT:    save %sp, -176, %sp
+; SPARC64-NEXT:    call __clzdi2
+; SPARC64-NEXT:    mov %i0, %o0
+; SPARC64-NEXT:    ret
+; SPARC64-NEXT:    restore %g0, %o0, %o0
+;
+; SPARC64-POPC-LABEL: i64_poison:
+; SPARC64-POPC:       ! %bb.0:
+; SPARC64-POPC-NEXT:    srlx %o0, 1, %o1
+; SPARC64-POPC-NEXT:    or %o0, %o1, %o0
+; SPARC64-POPC-NEXT:    srlx %o0, 2, %o1
+; SPARC64-POPC-NEXT:    or %o0, %o1, %o0
+; SPARC64-POPC-NEXT:    srlx %o0, 4, %o1
+; SPARC64-POPC-NEXT:    or %o0, %o1, %o0
+; SPARC64-POPC-NEXT:    srlx %o0, 8, %o1
+; SPARC64-POPC-NEXT:    or %o0, %o1, %o0
+; SPARC64-POPC-NEXT:    srlx %o0, 16, %o1
+; SPARC64-POPC-NEXT:    or %o0, %o1, %o0
+; SPARC64-POPC-NEXT:    srlx %o0, 32, %o1
+; SPARC64-POPC-NEXT:    or %o0, %o1, %o0
+; SPARC64-POPC-NEXT:    xor %o0, -1, %o0
+; SPARC64-POPC-NEXT:    retl
+; SPARC64-POPC-NEXT:    popc %o0, %o0
+;
+; SPARC64-VIS3-LABEL: i64_poison:
+; SPARC64-VIS3:       ! %bb.0:
+; SPARC64-VIS3-NEXT:    retl
+; SPARC64-VIS3-NEXT:    lzcnt %o0, %o0
   %ret = call i64 @llvm.ctlz.i64(i64 %x, i1 true)
   ret i64 %ret
 }

>From df2770a2872ebdc5bd18d6c79fec1ec933433acc Mon Sep 17 00:00:00 2001
From: Koakuma <koachan at protonmail.com>
Date: Thu, 17 Apr 2025 21:56:30 +0700
Subject: [PATCH 3/4] Adjust codegen parameters

Created using spr 1.3.5
---
 llvm/lib/Target/Sparc/SparcISelLowering.cpp | 2 ++
 llvm/lib/Target/Sparc/SparcISelLowering.h   | 6 ++++++
 2 files changed, 8 insertions(+)

diff --git a/llvm/lib/Target/Sparc/SparcISelLowering.cpp b/llvm/lib/Target/Sparc/SparcISelLowering.cpp
index 386a9bd72c965..4b61f588f18c8 100644
--- a/llvm/lib/Target/Sparc/SparcISelLowering.cpp
+++ b/llvm/lib/Target/Sparc/SparcISelLowering.cpp
@@ -3588,6 +3588,8 @@ bool SparcTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT,
          Imm.isZero();
 }
 
+bool SparcTargetLowering::isCtlzFast() const { return Subtarget->isVIS3(); }
+
 // Override to disable global variable loading on Linux.
 void SparcTargetLowering::insertSSPDeclarations(Module &M) const {
   if (!Subtarget->isTargetLinux())
diff --git a/llvm/lib/Target/Sparc/SparcISelLowering.h b/llvm/lib/Target/Sparc/SparcISelLowering.h
index c09e465f5d05e..ef87e20094c98 100644
--- a/llvm/lib/Target/Sparc/SparcISelLowering.h
+++ b/llvm/lib/Target/Sparc/SparcISelLowering.h
@@ -210,6 +210,12 @@ namespace llvm {
     bool isFPImmLegal(const APFloat &Imm, EVT VT,
                       bool ForCodeSize) const override;
 
+    bool isCtlzFast() const override;
+
+    bool isCheapToSpeculateCtlz(Type *Ty) const override {
+      return isCtlzFast();
+    }
+
     bool shouldInsertFencesForAtomic(const Instruction *I) const override {
       // FIXME: We insert fences for each atomics and generate
       // sub-optimal code for PSO/TSO. (Approximately nobody uses any

>From 5502caf555bdcbefd92a21f3bc952b803cb50fc8 Mon Sep 17 00:00:00 2001
From: Koakuma <koachan at protonmail.com>
Date: Thu, 17 Apr 2025 22:11:19 +0700
Subject: [PATCH 4/4] Adjust tests

Created using spr 1.3.5
---
 llvm/test/CodeGen/SPARC/ctlz.ll | 20 --------------------
 1 file changed, 20 deletions(-)

diff --git a/llvm/test/CodeGen/SPARC/ctlz.ll b/llvm/test/CodeGen/SPARC/ctlz.ll
index f3563c769f7f6..72505f221469e 100644
--- a/llvm/test/CodeGen/SPARC/ctlz.ll
+++ b/llvm/test/CodeGen/SPARC/ctlz.ll
@@ -39,17 +39,10 @@ define i32 @i32_nopoison(i32 %x) nounwind {
 ;
 ; SPARC-VIS3-LABEL: i32_nopoison:
 ; SPARC-VIS3:       ! %bb.0:
-; SPARC-VIS3-NEXT:    cmp %o0, 0
-; SPARC-VIS3-NEXT:    be .LBB0_2
-; SPARC-VIS3-NEXT:    nop
-; SPARC-VIS3-NEXT:  ! %bb.1: ! %cond.false
 ; SPARC-VIS3-NEXT:    srl %o0, 0, %o0
 ; SPARC-VIS3-NEXT:    lzcnt %o0, %o0
 ; SPARC-VIS3-NEXT:    retl
 ; SPARC-VIS3-NEXT:    add %o0, -32, %o0
-; SPARC-VIS3-NEXT:  .LBB0_2:
-; SPARC-VIS3-NEXT:    retl
-; SPARC-VIS3-NEXT:    mov 32, %o0
 ;
 ; SPARC64-LABEL: i32_nopoison:
 ; SPARC64:       ! %bb.0:
@@ -92,17 +85,10 @@ define i32 @i32_nopoison(i32 %x) nounwind {
 ;
 ; SPARC64-VIS3-LABEL: i32_nopoison:
 ; SPARC64-VIS3:       ! %bb.0:
-; SPARC64-VIS3-NEXT:    cmp %o0, 0
-; SPARC64-VIS3-NEXT:    be %icc, .LBB0_2
-; SPARC64-VIS3-NEXT:    nop
-; SPARC64-VIS3-NEXT:  ! %bb.1: ! %cond.false
 ; SPARC64-VIS3-NEXT:    srl %o0, 0, %o0
 ; SPARC64-VIS3-NEXT:    lzcnt %o0, %o0
 ; SPARC64-VIS3-NEXT:    retl
 ; SPARC64-VIS3-NEXT:    add %o0, -32, %o0
-; SPARC64-VIS3-NEXT:  .LBB0_2:
-; SPARC64-VIS3-NEXT:    retl
-; SPARC64-VIS3-NEXT:    mov 32, %o0
   %ret = call i32 @llvm.ctlz.i32(i32 %x, i1 false)
   ret i32 %ret
 }
@@ -320,14 +306,8 @@ define i64 @i64_nopoison(i64 %x) nounwind {
 ;
 ; SPARC64-VIS3-LABEL: i64_nopoison:
 ; SPARC64-VIS3:       ! %bb.0:
-; SPARC64-VIS3-NEXT:    brz %o0, .LBB2_2
-; SPARC64-VIS3-NEXT:    nop
-; SPARC64-VIS3-NEXT:  ! %bb.1: ! %cond.false
 ; SPARC64-VIS3-NEXT:    retl
 ; SPARC64-VIS3-NEXT:    lzcnt %o0, %o0
-; SPARC64-VIS3-NEXT:  .LBB2_2:
-; SPARC64-VIS3-NEXT:    retl
-; SPARC64-VIS3-NEXT:    mov 64, %o0
   %ret = call i64 @llvm.ctlz.i64(i64 %x, i1 false)
   ret i64 %ret
 }



More information about the llvm-branch-commits mailing list