[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
Wed Apr 16 19:11:32 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/2] 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/2] 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
}
More information about the llvm-branch-commits
mailing list