From 70b5a4fa51b6a2519b8a65ba4ecf81162d98a586 Mon Sep 17 00:00:00 2001 From: Koakuma Date: Tue, 15 Apr 2025 07:45:52 +0700 Subject: [PATCH 1/7] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20ch?= =?UTF-8?q?anges=20to=20main=20this=20commit=20is=20based=20on?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Created using spr 1.3.5 [skip ci] --- llvm/lib/Target/Sparc/SparcISelLowering.cpp | 17 ++- llvm/lib/Target/Sparc/SparcISelLowering.h | 3 + llvm/lib/Target/Sparc/SparcInstr64Bit.td | 2 + llvm/lib/Target/Sparc/SparcInstrVIS.td | 31 ++++- llvm/test/CodeGen/SPARC/2011-01-11-CC.ll | 118 ++++++++++++++++++ llvm/test/CodeGen/SPARC/float-constants.ll | 115 +++++++++++++++++ llvm/test/CodeGen/SPARC/multiply-extension.ll | 59 +++++++++ .../SPARC/smulo-128-legalisation-lowering.ll | 44 +++++++ .../SPARC/umulo-128-legalisation-lowering.ll | 33 +++++ 9 files changed, 418 insertions(+), 4 deletions(-) create mode 100644 llvm/test/CodeGen/SPARC/multiply-extension.ll diff --git a/llvm/lib/Target/Sparc/SparcISelLowering.cpp b/llvm/lib/Target/Sparc/SparcISelLowering.cpp index 85b8750d40f46..0ad261135651f 100644 --- a/llvm/lib/Target/Sparc/SparcISelLowering.cpp +++ b/llvm/lib/Target/Sparc/SparcISelLowering.cpp @@ -1737,6 +1737,11 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM, setOperationAction(ISD::SUBC, MVT::i32, Legal); setOperationAction(ISD::SUBE, MVT::i32, Legal); + if (Subtarget->isVIS3()) { + setOperationAction(ISD::ADDC, MVT::i64, Legal); + setOperationAction(ISD::ADDE, MVT::i64, Legal); + } + if (Subtarget->is64Bit()) { setOperationAction(ISD::BITCAST, MVT::f64, Expand); setOperationAction(ISD::BITCAST, MVT::i64, Expand); @@ -1849,8 +1854,10 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM, if (Subtarget->is64Bit()) { setOperationAction(ISD::UMUL_LOHI, MVT::i64, Expand); setOperationAction(ISD::SMUL_LOHI, MVT::i64, Expand); - setOperationAction(ISD::MULHU, MVT::i64, Expand); - setOperationAction(ISD::MULHS, MVT::i64, Expand); + setOperationAction(ISD::MULHU, MVT::i64, + Subtarget->isVIS3() ? Legal : Expand); + setOperationAction(ISD::MULHS, MVT::i64, + Subtarget->isVIS3() ? Legal : Expand); setOperationAction(ISD::SHL_PARTS, MVT::i64, Expand); setOperationAction(ISD::SRA_PARTS, MVT::i64, Expand); @@ -3560,6 +3567,12 @@ bool SparcTargetLowering::useLoadStackGuardNode(const Module &M) const { return true; } +bool SparcTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT, + bool ForCodeSize) const { + return Subtarget->isVIS() && (VT == MVT::f32 || VT == MVT::f64) && + Imm.isZero(); +} + // 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 1bee5f4cfe84d..c09e465f5d05e 100644 --- a/llvm/lib/Target/Sparc/SparcISelLowering.h +++ b/llvm/lib/Target/Sparc/SparcISelLowering.h @@ -207,6 +207,9 @@ namespace llvm { return VT != MVT::f128; } + bool isFPImmLegal(const APFloat &Imm, EVT VT, + bool ForCodeSize) const override; + 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 diff --git a/llvm/lib/Target/Sparc/SparcInstr64Bit.td b/llvm/lib/Target/Sparc/SparcInstr64Bit.td index 56fab2f26a19e..000612534e89d 100644 --- a/llvm/lib/Target/Sparc/SparcInstr64Bit.td +++ b/llvm/lib/Target/Sparc/SparcInstr64Bit.td @@ -157,9 +157,11 @@ def : Pat<(and i64:$lhs, (not i64:$rhs)), (ANDNrr $lhs, $rhs)>; def : Pat<(or i64:$lhs, (not i64:$rhs)), (ORNrr $lhs, $rhs)>; def : Pat<(not (xor i64:$lhs, i64:$rhs)), (XNORrr $lhs, $rhs)>; +def : Pat<(addc i64:$lhs, i64:$rhs), (ADDCCrr $lhs, $rhs)>, Requires<[HasVIS3]>; def : Pat<(add i64:$lhs, i64:$rhs), (ADDrr $lhs, $rhs)>; def : Pat<(sub i64:$lhs, i64:$rhs), (SUBrr $lhs, $rhs)>; +def : Pat<(addc i64:$lhs, (i64 simm13:$rhs)), (ADDCCri $lhs, imm:$rhs)>, Requires<[HasVIS3]>; def : Pat<(add i64:$lhs, (i64 simm13:$rhs)), (ADDri $lhs, imm:$rhs)>; def : Pat<(sub i64:$lhs, (i64 simm13:$rhs)), (SUBri $lhs, imm:$rhs)>; diff --git a/llvm/lib/Target/Sparc/SparcInstrVIS.td b/llvm/lib/Target/Sparc/SparcInstrVIS.td index 8ce8f37f34040..925bcdc9070fa 100644 --- a/llvm/lib/Target/Sparc/SparcInstrVIS.td +++ b/llvm/lib/Target/Sparc/SparcInstrVIS.td @@ -45,10 +45,10 @@ class VISInst2 opfval, string OpcStr, RegisterClass RC = DFPRegs> !strconcat(OpcStr, " $rs2, $rd")>; // For VIS Instructions with only rd operand. -let Constraints = "$rd = $f", rs1 = 0, rs2 = 0 in +let rs1 = 0, rs2 = 0 in class VISInstD opfval, string OpcStr, RegisterClass RC = DFPRegs> : VISInstFormat; // VIS 1 Instructions @@ -277,3 +277,30 @@ def UMULXHI : VISInst<0b000010110, "umulxhi", I64Regs>; def XMULX : VISInst<0b100010101, "xmulx", I64Regs>; def XMULXHI : VISInst<0b100010110, "xmulxhi", I64Regs>; } // Predicates = [IsVIS3] + +// FP immediate patterns. +def fpimm0 : PatLeaf<(fpimm), [{return N->isExactlyValue(+0.0);}]>; +def fpnegimm0 : PatLeaf<(fpimm), [{return N->isExactlyValue(-0.0);}]>; + +// VIS instruction patterns. +let Predicates = [HasVIS] in { +// Zero immediate. +def : Pat<(f64 fpimm0), (FZERO)>; +def : Pat<(f32 fpimm0), (FZEROS)>; +def : Pat<(f64 fpnegimm0), (FNEGD (FZERO))>; +def : Pat<(f32 fpnegimm0), (FNEGS (FZEROS))>; +} // Predicates = [HasVIS] + +// VIS3 instruction patterns. +let Predicates = [HasVIS3] in { +def : Pat<(i64 (adde i64:$lhs, i64:$rhs)), (ADDXCCC $lhs, $rhs)>; + +def : Pat<(i64 (mulhu i64:$lhs, i64:$rhs)), (UMULXHI $lhs, $rhs)>; +// Signed "MULXHI". +// Based on the formula presented in OSA2011 §7.140, but with bitops to select +// the values to be added. +def : Pat<(i64 (mulhs i64:$lhs, i64:$rhs)), + (SUBrr (UMULXHI $lhs, $rhs), + (ADDrr (ANDrr (SRAXri $lhs, 63), $rhs), + (ANDrr (SRAXri $rhs, 63), $lhs)))>; +} // Predicates = [HasVIS3] diff --git a/llvm/test/CodeGen/SPARC/2011-01-11-CC.ll b/llvm/test/CodeGen/SPARC/2011-01-11-CC.ll index 1560bc687b7dd..e05c47bfee766 100644 --- a/llvm/test/CodeGen/SPARC/2011-01-11-CC.ll +++ b/llvm/test/CodeGen/SPARC/2011-01-11-CC.ll @@ -2,6 +2,7 @@ ; RUN: llc -mtriple=sparc %s -o - | FileCheck %s -check-prefix=V8 ; RUN: llc -mtriple=sparc -mattr=v9 %s -o - | FileCheck %s -check-prefix=V9 ; RUN: llc -mtriple=sparc64-unknown-linux %s -o - | FileCheck %s -check-prefix=SPARC64 +; RUN: llc -mtriple=sparc64-unknown-linux -mattr=vis3 %s -o - | FileCheck %s -check-prefix=SPARC64-VIS3 define i32 @test_addx(i64 %a, i64 %b, i64 %c) nounwind { ; V8-LABEL: test_addx: @@ -60,6 +61,15 @@ define i32 @test_addx(i64 %a, i64 %b, i64 %c) nounwind { ; SPARC64-NEXT: movgu %xcc, 1, %o3 ; SPARC64-NEXT: retl ; SPARC64-NEXT: srl %o3, 0, %o0 +; +; SPARC64-VIS3-LABEL: test_addx: +; SPARC64-VIS3: ! %bb.0: ! %entry +; SPARC64-VIS3-NEXT: mov %g0, %o3 +; SPARC64-VIS3-NEXT: add %o0, %o1, %o0 +; SPARC64-VIS3-NEXT: cmp %o0, %o2 +; SPARC64-VIS3-NEXT: movgu %xcc, 1, %o3 +; SPARC64-VIS3-NEXT: retl +; SPARC64-VIS3-NEXT: srl %o3, 0, %o0 entry: %0 = add i64 %a, %b %1 = icmp ugt i64 %0, %c @@ -92,6 +102,13 @@ define i32 @test_select_int_icc(i32 %a, i32 %b, i32 %c) nounwind { ; SPARC64-NEXT: move %icc, %o1, %o2 ; SPARC64-NEXT: retl ; SPARC64-NEXT: mov %o2, %o0 +; +; SPARC64-VIS3-LABEL: test_select_int_icc: +; SPARC64-VIS3: ! %bb.0: ! %entry +; SPARC64-VIS3-NEXT: cmp %o0, 0 +; SPARC64-VIS3-NEXT: move %icc, %o1, %o2 +; SPARC64-VIS3-NEXT: retl +; SPARC64-VIS3-NEXT: mov %o2, %o0 entry: %0 = icmp eq i32 %a, 0 %1 = select i1 %0, i32 %b, i32 %c @@ -133,6 +150,13 @@ define float @test_select_fp_icc(i32 %a, float %f1, float %f2) nounwind { ; SPARC64-NEXT: cmp %o0, 0 ; SPARC64-NEXT: retl ; SPARC64-NEXT: fmovse %icc, %f3, %f0 +; +; SPARC64-VIS3-LABEL: test_select_fp_icc: +; SPARC64-VIS3: ! %bb.0: ! %entry +; SPARC64-VIS3-NEXT: fmovs %f5, %f0 +; SPARC64-VIS3-NEXT: cmp %o0, 0 +; SPARC64-VIS3-NEXT: retl +; SPARC64-VIS3-NEXT: fmovse %icc, %f3, %f0 entry: %0 = icmp eq i32 %a, 0 %1 = select i1 %0, float %f1, float %f2 @@ -182,6 +206,13 @@ define double @test_select_dfp_icc(i32 %a, double %f1, double %f2) nounwind { ; SPARC64-NEXT: cmp %o0, 0 ; SPARC64-NEXT: retl ; SPARC64-NEXT: fmovde %icc, %f2, %f0 +; +; SPARC64-VIS3-LABEL: test_select_dfp_icc: +; SPARC64-VIS3: ! %bb.0: ! %entry +; SPARC64-VIS3-NEXT: fmovd %f4, %f0 +; SPARC64-VIS3-NEXT: cmp %o0, 0 +; SPARC64-VIS3-NEXT: retl +; SPARC64-VIS3-NEXT: fmovde %icc, %f2, %f0 entry: %0 = icmp eq i32 %a, 0 %1 = select i1 %0, double %f1, double %f2 @@ -229,6 +260,17 @@ define i32 @test_select_int_fcc(float %f, i32 %a, i32 %b) nounwind { ; SPARC64-NEXT: fcmps %fcc0, %f1, %f0 ; SPARC64-NEXT: retl ; SPARC64-NEXT: movne %fcc0, %o1, %o0 +; +; SPARC64-VIS3-LABEL: test_select_int_fcc: +; SPARC64-VIS3: ! %bb.0: ! %entry +; SPARC64-VIS3-NEXT: sethi %h44(.LCPI4_0), %o0 +; SPARC64-VIS3-NEXT: add %o0, %m44(.LCPI4_0), %o0 +; SPARC64-VIS3-NEXT: sllx %o0, 12, %o0 +; SPARC64-VIS3-NEXT: ld [%o0+%l44(.LCPI4_0)], %f0 +; SPARC64-VIS3-NEXT: mov %o2, %o0 +; SPARC64-VIS3-NEXT: fcmps %fcc0, %f1, %f0 +; SPARC64-VIS3-NEXT: retl +; SPARC64-VIS3-NEXT: movne %fcc0, %o1, %o0 entry: %0 = fcmp une float %f, 0.000000e+00 %a.b = select i1 %0, i32 %a, i32 %b @@ -284,6 +326,17 @@ define float @test_select_fp_fcc(float %f, float %f1, float %f2) nounwind { ; SPARC64-NEXT: fcmps %fcc0, %f1, %f2 ; SPARC64-NEXT: retl ; SPARC64-NEXT: fmovsne %fcc0, %f3, %f0 +; +; SPARC64-VIS3-LABEL: test_select_fp_fcc: +; SPARC64-VIS3: ! %bb.0: ! %entry +; SPARC64-VIS3-NEXT: sethi %h44(.LCPI5_0), %o0 +; SPARC64-VIS3-NEXT: add %o0, %m44(.LCPI5_0), %o0 +; SPARC64-VIS3-NEXT: sllx %o0, 12, %o0 +; SPARC64-VIS3-NEXT: ld [%o0+%l44(.LCPI5_0)], %f2 +; SPARC64-VIS3-NEXT: fmovs %f5, %f0 +; SPARC64-VIS3-NEXT: fcmps %fcc0, %f1, %f2 +; SPARC64-VIS3-NEXT: retl +; SPARC64-VIS3-NEXT: fmovsne %fcc0, %f3, %f0 entry: %0 = fcmp une float %f, 0.000000e+00 %1 = select i1 %0, float %f1, float %f2 @@ -352,6 +405,18 @@ define double @test_select_dfp_fcc(double %f, double %f1, double %f2) nounwind { ; SPARC64-NEXT: fmovd %f4, %f0 ; SPARC64-NEXT: retl ; SPARC64-NEXT: nop +; +; SPARC64-VIS3-LABEL: test_select_dfp_fcc: +; SPARC64-VIS3: ! %bb.0: ! %entry +; SPARC64-VIS3-NEXT: sethi %h44(.LCPI6_0), %o0 +; SPARC64-VIS3-NEXT: add %o0, %m44(.LCPI6_0), %o0 +; SPARC64-VIS3-NEXT: sllx %o0, 12, %o0 +; SPARC64-VIS3-NEXT: ldd [%o0+%l44(.LCPI6_0)], %f6 +; SPARC64-VIS3-NEXT: fcmpd %fcc0, %f0, %f6 +; SPARC64-VIS3-NEXT: fmovdne %fcc0, %f2, %f4 +; SPARC64-VIS3-NEXT: fmovd %f4, %f0 +; SPARC64-VIS3-NEXT: retl +; SPARC64-VIS3-NEXT: nop entry: %0 = fcmp une double %f, 0.000000e+00 %1 = select i1 %0, double %f1, double %f2 @@ -453,6 +518,31 @@ define i32 @test_float_cc(double %a, double %b, i32 %c, i32 %d) nounwind { ; SPARC64-NEXT: ! %bb.4: ! %exit.0 ; SPARC64-NEXT: retl ; SPARC64-NEXT: mov %g0, %o0 +; +; SPARC64-VIS3-LABEL: test_float_cc: +; SPARC64-VIS3: ! %bb.0: ! %entry +; SPARC64-VIS3-NEXT: sethi %h44(.LCPI7_0), %o0 +; SPARC64-VIS3-NEXT: add %o0, %m44(.LCPI7_0), %o0 +; SPARC64-VIS3-NEXT: sllx %o0, 12, %o0 +; SPARC64-VIS3-NEXT: ldd [%o0+%l44(.LCPI7_0)], %f4 +; SPARC64-VIS3-NEXT: fcmpd %fcc0, %f0, %f4 +; SPARC64-VIS3-NEXT: fbuge %fcc0, .LBB7_3 +; SPARC64-VIS3-NEXT: nop +; SPARC64-VIS3-NEXT: ! %bb.1: ! %loop.2 +; SPARC64-VIS3-NEXT: fcmpd %fcc0, %f2, %f4 +; SPARC64-VIS3-NEXT: fbule %fcc0, .LBB7_3 +; SPARC64-VIS3-NEXT: nop +; SPARC64-VIS3-NEXT: ! %bb.2: ! %exit.1 +; SPARC64-VIS3-NEXT: retl +; SPARC64-VIS3-NEXT: mov 1, %o0 +; SPARC64-VIS3-NEXT: .LBB7_3: ! %loop +; SPARC64-VIS3-NEXT: ! =>This Inner Loop Header: Depth=1 +; SPARC64-VIS3-NEXT: cmp %o2, 10 +; SPARC64-VIS3-NEXT: be %icc, .LBB7_3 +; SPARC64-VIS3-NEXT: nop +; SPARC64-VIS3-NEXT: ! %bb.4: ! %exit.0 +; SPARC64-VIS3-NEXT: retl +; SPARC64-VIS3-NEXT: mov %g0, %o0 entry: %0 = fcmp uge double %a, 0.000000e+00 br i1 %0, label %loop, label %loop.2 @@ -558,6 +648,34 @@ define void @test_adde_sube(ptr %a, ptr %b, ptr %sum, ptr %diff) nounwind { ; SPARC64-NEXT: stx %i0, [%i3] ; SPARC64-NEXT: ret ; SPARC64-NEXT: restore +; +; SPARC64-VIS3-LABEL: test_adde_sube: +; SPARC64-VIS3: .register %g2, #scratch +; SPARC64-VIS3-NEXT: ! %bb.0: ! %entry +; SPARC64-VIS3-NEXT: save %sp, -128, %sp +; SPARC64-VIS3-NEXT: ldx [%i0+8], %i4 +; SPARC64-VIS3-NEXT: ldx [%i0], %i5 +; SPARC64-VIS3-NEXT: ldx [%i1+8], %g2 +; SPARC64-VIS3-NEXT: ldx [%i1], %i1 +; SPARC64-VIS3-NEXT: addcc %i4, %g2, %g2 +; SPARC64-VIS3-NEXT: addxccc %i5, %i1, %i1 +; SPARC64-VIS3-NEXT: stx %i1, [%i2] +; SPARC64-VIS3-NEXT: stx %g2, [%i2+8] +; SPARC64-VIS3-NEXT: !APP +; SPARC64-VIS3-NEXT: !NO_APP +; SPARC64-VIS3-NEXT: ldx [%i0+8], %i1 +; SPARC64-VIS3-NEXT: mov %g0, %i2 +; SPARC64-VIS3-NEXT: ldx [%i0], %i0 +; SPARC64-VIS3-NEXT: cmp %i4, %i1 +; SPARC64-VIS3-NEXT: movcs %xcc, 1, %i2 +; SPARC64-VIS3-NEXT: srl %i2, 0, %i2 +; SPARC64-VIS3-NEXT: sub %i5, %i0, %i0 +; SPARC64-VIS3-NEXT: sub %i0, %i2, %i0 +; SPARC64-VIS3-NEXT: sub %i4, %i1, %i1 +; SPARC64-VIS3-NEXT: stx %i1, [%i3+8] +; SPARC64-VIS3-NEXT: stx %i0, [%i3] +; SPARC64-VIS3-NEXT: ret +; SPARC64-VIS3-NEXT: restore entry: %0 = bitcast ptr %a to ptr %1 = bitcast ptr %b to ptr diff --git a/llvm/test/CodeGen/SPARC/float-constants.ll b/llvm/test/CodeGen/SPARC/float-constants.ll index b04ec68ed3d7e..440c75bfca9f9 100644 --- a/llvm/test/CodeGen/SPARC/float-constants.ll +++ b/llvm/test/CodeGen/SPARC/float-constants.ll @@ -1,6 +1,7 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2 ; RUN: llc < %s -mtriple=sparc | FileCheck %s ; RUN: llc < %s -mtriple=sparcel | FileCheck %s --check-prefix=CHECK-LE +; RUN: llc < %s -mtriple=sparcv9 -mattr=+vis | FileCheck %s --check-prefix=CHECK-VIS ;; Bitcast should not do a runtime conversion, but rather emit a ;; constant into integer registers directly. @@ -17,6 +18,12 @@ define <2 x i32> @bitcast() nounwind { ; CHECK-LE-NEXT: sethi 1049856, %o1 ; CHECK-LE-NEXT: retl ; CHECK-LE-NEXT: mov %g0, %o0 +; +; CHECK-VIS-LABEL: bitcast: +; CHECK-VIS: ! %bb.0: +; CHECK-VIS-NEXT: sethi 1049856, %o0 +; CHECK-VIS-NEXT: retl +; CHECK-VIS-NEXT: mov %g0, %o1 %1 = bitcast double 5.0 to <2 x i32> ret <2 x i32> %1 } @@ -43,6 +50,17 @@ define void @test_call() nounwind { ; CHECK-LE-NEXT: mov %g0, %o0 ; CHECK-LE-NEXT: ret ; CHECK-LE-NEXT: restore +; +; CHECK-VIS-LABEL: test_call: +; CHECK-VIS: ! %bb.0: +; CHECK-VIS-NEXT: save %sp, -176, %sp +; CHECK-VIS-NEXT: sethi %h44(.LCPI1_0), %i0 +; CHECK-VIS-NEXT: add %i0, %m44(.LCPI1_0), %i0 +; CHECK-VIS-NEXT: sllx %i0, 12, %i0 +; CHECK-VIS-NEXT: call a +; CHECK-VIS-NEXT: ldd [%i0+%l44(.LCPI1_0)], %f0 +; CHECK-VIS-NEXT: ret +; CHECK-VIS-NEXT: restore call void @a(double 5.0) ret void } @@ -75,6 +93,103 @@ define double @test_intrins_call() nounwind { ; CHECK-LE-NEXT: mov %o1, %o3 ; CHECK-LE-NEXT: ret ; CHECK-LE-NEXT: restore +; +; CHECK-VIS-LABEL: test_intrins_call: +; CHECK-VIS: ! %bb.0: +; CHECK-VIS-NEXT: save %sp, -176, %sp +; CHECK-VIS-NEXT: sethi %h44(.LCPI2_0), %i0 +; CHECK-VIS-NEXT: add %i0, %m44(.LCPI2_0), %i0 +; CHECK-VIS-NEXT: sllx %i0, 12, %i0 +; CHECK-VIS-NEXT: ldd [%i0+%l44(.LCPI2_0)], %f0 +; CHECK-VIS-NEXT: fmovd %f0, %f2 +; CHECK-VIS-NEXT: call pow +; CHECK-VIS-NEXT: nop +; CHECK-VIS-NEXT: ret +; CHECK-VIS-NEXT: restore %1 = call double @llvm.pow.f64(double 2.0, double 2.0) ret double %1 } + +;; When we have VIS, f32/f64 zero constant should be materialized from fzero/fzeros. + +define double @pos_zero_double() nounwind { +; CHECK-LABEL: pos_zero_double: +; CHECK: ! %bb.0: +; CHECK-NEXT: sethi %hi(.LCPI3_0), %o0 +; CHECK-NEXT: retl +; CHECK-NEXT: ldd [%o0+%lo(.LCPI3_0)], %f0 +; +; CHECK-LE-LABEL: pos_zero_double: +; CHECK-LE: ! %bb.0: +; CHECK-LE-NEXT: sethi %hi(.LCPI3_0), %o0 +; CHECK-LE-NEXT: retl +; CHECK-LE-NEXT: ldd [%o0+%lo(.LCPI3_0)], %f0 +; +; CHECK-VIS-LABEL: pos_zero_double: +; CHECK-VIS: ! %bb.0: +; CHECK-VIS-NEXT: retl +; CHECK-VIS-NEXT: fzero %f0 + ret double +0.0 +} + +define double @neg_zero_double() nounwind { +; CHECK-LABEL: neg_zero_double: +; CHECK: ! %bb.0: +; CHECK-NEXT: sethi %hi(.LCPI4_0), %o0 +; CHECK-NEXT: retl +; CHECK-NEXT: ldd [%o0+%lo(.LCPI4_0)], %f0 +; +; CHECK-LE-LABEL: neg_zero_double: +; CHECK-LE: ! %bb.0: +; CHECK-LE-NEXT: sethi %hi(.LCPI4_0), %o0 +; CHECK-LE-NEXT: retl +; CHECK-LE-NEXT: ldd [%o0+%lo(.LCPI4_0)], %f0 +; +; CHECK-VIS-LABEL: neg_zero_double: +; CHECK-VIS: ! %bb.0: +; CHECK-VIS-NEXT: fzero %f0 +; CHECK-VIS-NEXT: retl +; CHECK-VIS-NEXT: fnegd %f0, %f0 + ret double -0.0 +} + +define float @pos_zero_float() nounwind { +; CHECK-LABEL: pos_zero_float: +; CHECK: ! %bb.0: +; CHECK-NEXT: sethi %hi(.LCPI5_0), %o0 +; CHECK-NEXT: retl +; CHECK-NEXT: ld [%o0+%lo(.LCPI5_0)], %f0 +; +; CHECK-LE-LABEL: pos_zero_float: +; CHECK-LE: ! %bb.0: +; CHECK-LE-NEXT: sethi %hi(.LCPI5_0), %o0 +; CHECK-LE-NEXT: retl +; CHECK-LE-NEXT: ld [%o0+%lo(.LCPI5_0)], %f0 +; +; CHECK-VIS-LABEL: pos_zero_float: +; CHECK-VIS: ! %bb.0: +; CHECK-VIS-NEXT: retl +; CHECK-VIS-NEXT: fzeros %f0 + ret float +0.0 +} + +define float @neg_zero_float() nounwind { +; CHECK-LABEL: neg_zero_float: +; CHECK: ! %bb.0: +; CHECK-NEXT: sethi %hi(.LCPI6_0), %o0 +; CHECK-NEXT: retl +; CHECK-NEXT: ld [%o0+%lo(.LCPI6_0)], %f0 +; +; CHECK-LE-LABEL: neg_zero_float: +; CHECK-LE: ! %bb.0: +; CHECK-LE-NEXT: sethi %hi(.LCPI6_0), %o0 +; CHECK-LE-NEXT: retl +; CHECK-LE-NEXT: ld [%o0+%lo(.LCPI6_0)], %f0 +; +; CHECK-VIS-LABEL: neg_zero_float: +; CHECK-VIS: ! %bb.0: +; CHECK-VIS-NEXT: fzeros %f0 +; CHECK-VIS-NEXT: retl +; CHECK-VIS-NEXT: fnegs %f0, %f0 + ret float -0.0 +} diff --git a/llvm/test/CodeGen/SPARC/multiply-extension.ll b/llvm/test/CodeGen/SPARC/multiply-extension.ll new file mode 100644 index 0000000000000..4d752ff101ca2 --- /dev/null +++ b/llvm/test/CodeGen/SPARC/multiply-extension.ll @@ -0,0 +1,59 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 +; RUN: llc < %s -mtriple=sparcv9 | FileCheck %s -check-prefix=V9 +; RUN: llc < %s -mtriple=sparcv9 -mattr=+vis3 | FileCheck %s -check-prefix=VIS3 + +define i128 @signed_multiply_extend(i64 %0, i64 %1) nounwind { +; V9-LABEL: signed_multiply_extend: +; V9: ! %bb.0: +; V9-NEXT: save %sp, -176, %sp +; V9-NEXT: srax %i0, 63, %o2 +; V9-NEXT: srax %i1, 63, %o0 +; V9-NEXT: mov %i1, %o1 +; V9-NEXT: call __multi3 +; V9-NEXT: mov %i0, %o3 +; V9-NEXT: mov %o0, %i0 +; V9-NEXT: ret +; V9-NEXT: restore %g0, %o1, %o1 +; +; VIS3-LABEL: signed_multiply_extend: +; VIS3: ! %bb.0: +; VIS3-NEXT: srax %o0, 63, %o2 +; VIS3-NEXT: and %o2, %o1, %o2 +; VIS3-NEXT: srax %o1, 63, %o3 +; VIS3-NEXT: and %o3, %o0, %o3 +; VIS3-NEXT: add %o3, %o2, %o2 +; VIS3-NEXT: umulxhi %o1, %o0, %o3 +; VIS3-NEXT: sub %o3, %o2, %o2 +; VIS3-NEXT: mulx %o1, %o0, %o1 +; VIS3-NEXT: retl +; VIS3-NEXT: mov %o2, %o0 + %3 = sext i64 %0 to i128 + %4 = sext i64 %1 to i128 + %5 = mul nsw i128 %4, %3 + ret i128 %5 +} + +define i128 @unsigned_multiply_extend(i64 %0, i64 %1) nounwind { +; V9-LABEL: unsigned_multiply_extend: +; V9: ! %bb.0: +; V9-NEXT: save %sp, -176, %sp +; V9-NEXT: mov %g0, %o0 +; V9-NEXT: mov %i1, %o1 +; V9-NEXT: mov %g0, %o2 +; V9-NEXT: call __multi3 +; V9-NEXT: mov %i0, %o3 +; V9-NEXT: mov %o0, %i0 +; V9-NEXT: ret +; V9-NEXT: restore %g0, %o1, %o1 +; +; VIS3-LABEL: unsigned_multiply_extend: +; VIS3: ! %bb.0: +; VIS3-NEXT: umulxhi %o1, %o0, %o2 +; VIS3-NEXT: mulx %o1, %o0, %o1 +; VIS3-NEXT: retl +; VIS3-NEXT: mov %o2, %o0 + %3 = zext i64 %0 to i128 + %4 = zext i64 %1 to i128 + %5 = mul nuw i128 %4, %3 + ret i128 %5 +} diff --git a/llvm/test/CodeGen/SPARC/smulo-128-legalisation-lowering.ll b/llvm/test/CodeGen/SPARC/smulo-128-legalisation-lowering.ll index 07e4c408a3ff0..1e5ab7922de08 100644 --- a/llvm/test/CodeGen/SPARC/smulo-128-legalisation-lowering.ll +++ b/llvm/test/CodeGen/SPARC/smulo-128-legalisation-lowering.ll @@ -1,6 +1,7 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc < %s -mtriple=sparc-unknown-linux-gnu | FileCheck %s --check-prefixes=SPARC ; RUN: llc < %s -mtriple=sparc64-unknown-linux-gnu | FileCheck %s --check-prefixes=SPARC64 +; RUN: llc < %s -mtriple=sparc64-unknown-linux-gnu -mattr=vis3 | FileCheck %s --check-prefixes=SPARC64-VIS3 define { i128, i8 } @muloti_test(i128 %l, i128 %r) nounwind { ; SPARC-LABEL: muloti_test: @@ -213,6 +214,49 @@ define { i128, i8 } @muloti_test(i128 %l, i128 %r) nounwind { ; SPARC64-NEXT: srl %i3, 0, %i2 ; SPARC64-NEXT: ret ; SPARC64-NEXT: restore +; +; SPARC64-VIS3-LABEL: muloti_test: +; SPARC64-VIS3: .register %g2, #scratch +; SPARC64-VIS3-NEXT: .register %g3, #scratch +; SPARC64-VIS3-NEXT: ! %bb.0: ! %start +; SPARC64-VIS3-NEXT: save %sp, -128, %sp +; SPARC64-VIS3-NEXT: mov %g0, %i5 +; SPARC64-VIS3-NEXT: umulxhi %i0, %i3, %i4 +; SPARC64-VIS3-NEXT: srax %i0, 63, %g2 +; SPARC64-VIS3-NEXT: mulx %g2, %i3, %g3 +; SPARC64-VIS3-NEXT: add %i4, %g3, %i4 +; SPARC64-VIS3-NEXT: umulxhi %i1, %i3, %g3 +; SPARC64-VIS3-NEXT: mulx %i0, %i3, %g4 +; SPARC64-VIS3-NEXT: addcc %g4, %g3, %g3 +; SPARC64-VIS3-NEXT: addxccc %i4, %g0, %g4 +; SPARC64-VIS3-NEXT: umulxhi %i1, %i2, %i4 +; SPARC64-VIS3-NEXT: srax %i2, 63, %g5 +; SPARC64-VIS3-NEXT: mulx %i1, %g5, %l0 +; SPARC64-VIS3-NEXT: add %i4, %l0, %l0 +; SPARC64-VIS3-NEXT: mulx %i1, %i2, %i4 +; SPARC64-VIS3-NEXT: addcc %i4, %g3, %i4 +; SPARC64-VIS3-NEXT: addxccc %l0, %g0, %g3 +; SPARC64-VIS3-NEXT: srax %g3, 63, %l0 +; SPARC64-VIS3-NEXT: addcc %g4, %g3, %g3 +; SPARC64-VIS3-NEXT: srax %g4, 63, %g4 +; SPARC64-VIS3-NEXT: addxccc %g4, %l0, %g4 +; SPARC64-VIS3-NEXT: and %g5, %i0, %g5 +; SPARC64-VIS3-NEXT: and %g2, %i2, %g2 +; SPARC64-VIS3-NEXT: add %g2, %g5, %g2 +; SPARC64-VIS3-NEXT: umulxhi %i0, %i2, %g5 +; SPARC64-VIS3-NEXT: sub %g5, %g2, %g2 +; SPARC64-VIS3-NEXT: mulx %i0, %i2, %i0 +; SPARC64-VIS3-NEXT: addcc %i0, %g3, %i0 +; SPARC64-VIS3-NEXT: addxccc %g2, %g4, %i2 +; SPARC64-VIS3-NEXT: srax %i4, 63, %g2 +; SPARC64-VIS3-NEXT: xor %i2, %g2, %i2 +; SPARC64-VIS3-NEXT: xor %i0, %g2, %i0 +; SPARC64-VIS3-NEXT: or %i0, %i2, %i0 +; SPARC64-VIS3-NEXT: movrnz %i0, 1, %i5 +; SPARC64-VIS3-NEXT: mulx %i1, %i3, %i1 +; SPARC64-VIS3-NEXT: srl %i5, 0, %i2 +; SPARC64-VIS3-NEXT: ret +; SPARC64-VIS3-NEXT: restore %g0, %i4, %o0 start: %0 = tail call { i128, i1 } @llvm.smul.with.overflow.i128(i128 %l, i128 %r) %1 = extractvalue { i128, i1 } %0, 0 diff --git a/llvm/test/CodeGen/SPARC/umulo-128-legalisation-lowering.ll b/llvm/test/CodeGen/SPARC/umulo-128-legalisation-lowering.ll index 01383a00c2619..3bdb45ae51a93 100644 --- a/llvm/test/CodeGen/SPARC/umulo-128-legalisation-lowering.ll +++ b/llvm/test/CodeGen/SPARC/umulo-128-legalisation-lowering.ll @@ -1,6 +1,7 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc < %s -mtriple=sparc-unknown-linux-gnu | FileCheck %s --check-prefixes=SPARC ; RUN: llc < %s -mtriple=sparc64-unknown-linux-gnu | FileCheck %s --check-prefixes=SPARC64 +; RUN: llc < %s -mtriple=sparc64-unknown-linux-gnu -mattr=vis3 | FileCheck %s --check-prefixes=SPARC64-VIS3 define { i128, i8 } @muloti_test(i128 %l, i128 %r) nounwind { ; SPARC-LABEL: muloti_test: @@ -199,6 +200,38 @@ define { i128, i8 } @muloti_test(i128 %l, i128 %r) nounwind { ; SPARC64-NEXT: mov %i1, %i0 ; SPARC64-NEXT: ret ; SPARC64-NEXT: restore %g0, %o1, %o1 +; +; SPARC64-VIS3-LABEL: muloti_test: +; SPARC64-VIS3: .register %g2, #scratch +; SPARC64-VIS3-NEXT: .register %g3, #scratch +; SPARC64-VIS3-NEXT: ! %bb.0: ! %start +; SPARC64-VIS3-NEXT: save %sp, -128, %sp +; SPARC64-VIS3-NEXT: mov %g0, %i5 +; SPARC64-VIS3-NEXT: mov %g0, %g2 +; SPARC64-VIS3-NEXT: mov %g0, %g3 +; SPARC64-VIS3-NEXT: mov %g0, %g4 +; SPARC64-VIS3-NEXT: mov %g0, %g5 +; SPARC64-VIS3-NEXT: mulx %i2, %i1, %i4 +; SPARC64-VIS3-NEXT: mulx %i0, %i3, %l0 +; SPARC64-VIS3-NEXT: add %l0, %i4, %i4 +; SPARC64-VIS3-NEXT: umulxhi %i1, %i3, %l0 +; SPARC64-VIS3-NEXT: add %l0, %i4, %i4 +; SPARC64-VIS3-NEXT: cmp %i4, %l0 +; SPARC64-VIS3-NEXT: movrnz %i2, 1, %g2 +; SPARC64-VIS3-NEXT: movrnz %i0, 1, %g3 +; SPARC64-VIS3-NEXT: and %g3, %g2, %g2 +; SPARC64-VIS3-NEXT: umulxhi %i0, %i3, %i0 +; SPARC64-VIS3-NEXT: movrnz %i0, 1, %g4 +; SPARC64-VIS3-NEXT: movcs %xcc, 1, %i5 +; SPARC64-VIS3-NEXT: or %g2, %g4, %i0 +; SPARC64-VIS3-NEXT: umulxhi %i2, %i1, %i2 +; SPARC64-VIS3-NEXT: movrnz %i2, 1, %g5 +; SPARC64-VIS3-NEXT: or %i0, %g5, %i0 +; SPARC64-VIS3-NEXT: or %i0, %i5, %i0 +; SPARC64-VIS3-NEXT: mulx %i1, %i3, %i1 +; SPARC64-VIS3-NEXT: srl %i0, 0, %i2 +; SPARC64-VIS3-NEXT: ret +; SPARC64-VIS3-NEXT: restore %g0, %i4, %o0 start: %0 = tail call { i128, i1 } @llvm.umul.with.overflow.i128(i128 %l, i128 %r) %1 = extractvalue { i128, i1 } %0, 0 From 5e8bff2d300a95d94746ea58ea2dd18df0e096a5 Mon Sep 17 00:00:00 2001 From: Koakuma Date: Tue, 15 Apr 2025 23:52:23 +0700 Subject: [PATCH 2/7] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20ch?= =?UTF-8?q?anges=20introduced=20through=20rebase?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Created using spr 1.3.5 [skip ci] --- llvm/lib/Target/Sparc/SparcInstrVIS.td | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/Sparc/SparcInstrVIS.td b/llvm/lib/Target/Sparc/SparcInstrVIS.td index 925bcdc9070fa..771f6f0d061e1 100644 --- a/llvm/lib/Target/Sparc/SparcInstrVIS.td +++ b/llvm/lib/Target/Sparc/SparcInstrVIS.td @@ -279,8 +279,8 @@ def XMULXHI : VISInst<0b100010110, "xmulxhi", I64Regs>; } // Predicates = [IsVIS3] // FP immediate patterns. -def fpimm0 : PatLeaf<(fpimm), [{return N->isExactlyValue(+0.0);}]>; -def fpnegimm0 : PatLeaf<(fpimm), [{return N->isExactlyValue(-0.0);}]>; +def fpimm0 : FPImmLeaf; +def fpnegimm0 : FPImmLeaf; // VIS instruction patterns. let Predicates = [HasVIS] in { From a4deacfd37e48f93c63c02de6e582d797b471ea4 Mon Sep 17 00:00:00 2001 From: Koakuma Date: Wed, 16 Apr 2025 08:18:18 +0700 Subject: [PATCH 3/7] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20ch?= =?UTF-8?q?anges=20introduced=20through=20rebase?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Created using spr 1.3.5 [skip ci] --- llvm/lib/Target/Sparc/SparcInstrVIS.td | 1 + 1 file changed, 1 insertion(+) diff --git a/llvm/lib/Target/Sparc/SparcInstrVIS.td b/llvm/lib/Target/Sparc/SparcInstrVIS.td index 771f6f0d061e1..d9fe3b49821e5 100644 --- a/llvm/lib/Target/Sparc/SparcInstrVIS.td +++ b/llvm/lib/Target/Sparc/SparcInstrVIS.td @@ -299,6 +299,7 @@ def : Pat<(i64 (mulhu i64:$lhs, i64:$rhs)), (UMULXHI $lhs, $rhs)>; // Signed "MULXHI". // Based on the formula presented in OSA2011 §7.140, but with bitops to select // the values to be added. +// TODO: This expansion should probably be moved to DAG legalization phase. def : Pat<(i64 (mulhs i64:$lhs, i64:$rhs)), (SUBrr (UMULXHI $lhs, $rhs), (ADDrr (ANDrr (SRAXri $lhs, 63), $rhs), From 6e865810ea2acaf636a4759fd4ffc67aa3dbb848 Mon Sep 17 00:00:00 2001 From: Koakuma Date: Thu, 17 Apr 2025 08:24:54 +0700 Subject: [PATCH 4/7] 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 Date: Thu, 17 Apr 2025 09:11:17 +0700 Subject: [PATCH 5/7] 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 Date: Thu, 17 Apr 2025 21:56:30 +0700 Subject: [PATCH 6/7] 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 Date: Thu, 17 Apr 2025 22:11:19 +0700 Subject: [PATCH 7/7] 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 }