[llvm] [SPARC] Add TTI implementation for getPopcntSupport (PR #178843)

via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 9 07:31:32 PST 2026


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

>From 442ef8e9d9bb60969769a5a487d1bdf689366729 Mon Sep 17 00:00:00 2001
From: Koakuma <koachan at protonmail.com>
Date: Thu, 29 Jan 2026 18:53:40 +0700
Subject: [PATCH 1/8] [SPARC] Add basic TTI implementation

This is to inform the middle-end transform passes about the capabilities
of the processor.

This should solve two issues:
- Popcount loops now gets converted properly to `popc`, if available
  (https://github.com/llvm/llvm-project/issues/171969); and
- Fixes the `find-last` test, which fails to build because LoopVectorizePass
  mistakenly thinks that the backend understands vector types, when in fact
  it doesn't (https://github.com/sparclinux/issues/issues/69).
---
 llvm/lib/Target/Sparc/CMakeLists.txt          |   3 +
 llvm/lib/Target/Sparc/SparcTargetMachine.cpp  |   6 +
 llvm/lib/Target/Sparc/SparcTargetMachine.h    |   1 +
 .../Target/Sparc/SparcTargetTransformInfo.cpp | 109 ++++++++++++++++++
 .../Target/Sparc/SparcTargetTransformInfo.h   |  72 ++++++++++++
 5 files changed, 191 insertions(+)
 create mode 100644 llvm/lib/Target/Sparc/SparcTargetTransformInfo.cpp
 create mode 100644 llvm/lib/Target/Sparc/SparcTargetTransformInfo.h

diff --git a/llvm/lib/Target/Sparc/CMakeLists.txt b/llvm/lib/Target/Sparc/CMakeLists.txt
index f682719ac483f..5db9dbf623858 100644
--- a/llvm/lib/Target/Sparc/CMakeLists.txt
+++ b/llvm/lib/Target/Sparc/CMakeLists.txt
@@ -30,8 +30,10 @@ add_llvm_target(SparcCodeGen
   SparcSubtarget.cpp
   SparcTargetMachine.cpp
   SparcTargetObjectFile.cpp
+  SparcTargetTransformInfo.cpp
 
   LINK_COMPONENTS
+  Analysis
   AsmPrinter
   CodeGen
   CodeGenTypes
@@ -43,6 +45,7 @@ add_llvm_target(SparcCodeGen
   Support
   Target
   TargetParser
+  TransformUtils
 
   ADD_TO_COMPONENT
   Sparc
diff --git a/llvm/lib/Target/Sparc/SparcTargetMachine.cpp b/llvm/lib/Target/Sparc/SparcTargetMachine.cpp
index 27ab57c11cf71..b9f1ad5331d4b 100644
--- a/llvm/lib/Target/Sparc/SparcTargetMachine.cpp
+++ b/llvm/lib/Target/Sparc/SparcTargetMachine.cpp
@@ -14,6 +14,7 @@
 #include "Sparc.h"
 #include "SparcMachineFunctionInfo.h"
 #include "SparcTargetObjectFile.h"
+#include "SparcTargetTransformInfo.h"
 #include "TargetInfo/SparcTargetInfo.h"
 #include "llvm/CodeGen/Passes.h"
 #include "llvm/CodeGen/TargetPassConfig.h"
@@ -149,6 +150,11 @@ TargetPassConfig *SparcTargetMachine::createPassConfig(PassManagerBase &PM) {
   return new SparcPassConfig(*this, PM);
 }
 
+TargetTransformInfo
+SparcTargetMachine::getTargetTransformInfo(const Function &F) const {
+  return TargetTransformInfo(std::make_unique<SparcTTIImpl>(this, F));
+}
+
 void SparcPassConfig::addIRPasses() {
   addPass(createAtomicExpandLegacyPass());
 
diff --git a/llvm/lib/Target/Sparc/SparcTargetMachine.h b/llvm/lib/Target/Sparc/SparcTargetMachine.h
index e7d038c5779d4..2fbfd397325b6 100644
--- a/llvm/lib/Target/Sparc/SparcTargetMachine.h
+++ b/llvm/lib/Target/Sparc/SparcTargetMachine.h
@@ -40,6 +40,7 @@ class SparcTargetMachine : public CodeGenTargetMachineImpl {
   TargetLoweringObjectFile *getObjFileLowering() const override {
     return TLOF.get();
   }
+  TargetTransformInfo getTargetTransformInfo(const Function &F) const override;
 
   MachineFunctionInfo *
   createMachineFunctionInfo(BumpPtrAllocator &Allocator, const Function &F,
diff --git a/llvm/lib/Target/Sparc/SparcTargetTransformInfo.cpp b/llvm/lib/Target/Sparc/SparcTargetTransformInfo.cpp
new file mode 100644
index 0000000000000..d0fe94fb6ff73
--- /dev/null
+++ b/llvm/lib/Target/Sparc/SparcTargetTransformInfo.cpp
@@ -0,0 +1,109 @@
+//===-- SparcTargetTransformInfo.cpp - SPARC specific TTI -----------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "SparcTargetTransformInfo.h"
+#include "llvm/Support/MathExtras.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "sparctti"
+
+InstructionCost
+SparcTTIImpl::getIntImmCost(const APInt &Imm, Type *Ty,
+                            TTI::TargetCostKind CostKind) const {
+  assert(Ty->isIntegerTy());
+  unsigned BitSize = Ty->getPrimitiveSizeInBits();
+
+  if (BitSize <= 64) {
+    // Small constants can be folded into instruction's immediate field.
+    if (isInt<13>(Imm.getSExtValue()))
+      return TTI::TCC_Free;
+
+    // Medium constants loaded via set.
+    if (isUInt<32>(Imm.getZExtValue()))
+      return TTI::TCC_Basic;
+
+    // Large constants loaded via setx on 64-bit targets.
+    if (ST->is64Bit())
+      return 3 * TTI::TCC_Basic;
+  }
+
+  // Very large constants load from constant pool.
+  return TTI::TCC_Expensive;
+}
+
+InstructionCost SparcTTIImpl::getIntImmCostInst(unsigned Opcode, unsigned Idx,
+                                                const APInt &Imm, Type *Ty,
+                                                TTI::TargetCostKind CostKind,
+                                                Instruction *Inst) const {
+  assert(Ty->isIntegerTy());
+
+  switch (Opcode) {
+  case Instruction::Shl:
+  case Instruction::LShr:
+  case Instruction::AShr:
+    // Always return TCC_Free for the shift value of a shift instruction.
+    return (Idx == 1) ? TTI::TCC_Free : TTI::TCC_Basic;
+  }
+
+  // All other instructions have the same 13-bit immediate field so we can just
+  // pass it here.
+  return getIntImmCost(Imm, Ty, CostKind);
+}
+
+TargetTransformInfo::PopcntSupportKind
+SparcTTIImpl::getPopcntSupport(unsigned TyWidth) const {
+  assert(isPowerOf2_32(TyWidth) && "Type width must be power of 2");
+  if (ST->usePopc())
+    return TTI::PSK_FastHardware;
+  return TTI::PSK_Software;
+}
+
+unsigned SparcTTIImpl::getRegisterClassForType(bool Vector, Type *Ty) const {
+  if (Vector)
+    return FPRRC;
+  if (Ty &&
+      (Ty->getScalarType()->isFloatTy() || Ty->getScalarType()->isDoubleTy()))
+    return FPRRC;
+  if (Ty && (Ty->getScalarType()->isFP128Ty()))
+    return FP128RRC;
+  return GPRRC;
+}
+
+unsigned SparcTTIImpl::getNumberOfRegisters(unsigned ClassID) const {
+  switch (ClassID) {
+  case GPRRC:
+    // %g0, %g6, %g7, %o6, %i6, and %i7 are used for special purposes so we
+    // discount them here.
+    return 26;
+  case FPRRC:
+    return 32;
+  case FP128RRC:
+    return 16;
+  }
+
+  llvm_unreachable("Unsupported register class");
+}
+
+TypeSize
+SparcTTIImpl::getRegisterBitWidth(TargetTransformInfo::RegisterKind K) const {
+  switch (K) {
+  case TargetTransformInfo::RGK_Scalar:
+    // TODO When targeting V8+ ABI, G and O registers are 64-bit.
+    return TypeSize::getFixed(ST->is64Bit() ? 64 : 32);
+  case TargetTransformInfo::RGK_FixedWidthVector:
+    // TODO We have vector capabilities as part of the VIS extensions, but the
+    // codegen doesn't currently use it. Revisit this when vector codegen is
+    // ready.
+    return TypeSize::getFixed(0);
+  case TargetTransformInfo::RGK_ScalableVector:
+    return TypeSize::getScalable(0);
+  }
+
+  llvm_unreachable("Unsupported register kind");
+}
diff --git a/llvm/lib/Target/Sparc/SparcTargetTransformInfo.h b/llvm/lib/Target/Sparc/SparcTargetTransformInfo.h
new file mode 100644
index 0000000000000..042fe498f2a76
--- /dev/null
+++ b/llvm/lib/Target/Sparc/SparcTargetTransformInfo.h
@@ -0,0 +1,72 @@
+//===-- SparcTargetTransformInfo.cpp - SPARC specific TTI--------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// This file a TargetTransformInfoImplBase conforming object specific to the
+/// SPARC target machine. It uses the target's detailed information to
+/// provide more precise answers to certain TTI queries, while letting the
+/// target independent and default TTI implementations handle the rest.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_SPARC_SPARCTARGETTRANSFORMINFO_H
+#define LLVM_LIB_TARGET_SPARC_SPARCTARGETTRANSFORMINFO_H
+
+#include "SparcTargetMachine.h"
+#include "llvm/Analysis/TargetTransformInfo.h"
+#include "llvm/CodeGen/BasicTTIImpl.h"
+
+namespace llvm {
+
+class SparcTTIImpl final : public BasicTTIImplBase<SparcTTIImpl> {
+  typedef BasicTTIImplBase<SparcTTIImpl> BaseT;
+  typedef TargetTransformInfo TTI;
+  friend BaseT;
+
+  const SparcSubtarget *ST;
+  const SparcTargetLowering *TLI;
+
+  const SparcSubtarget *getST() const { return ST; }
+  const SparcTargetLowering *getTLI() const { return TLI; }
+
+public:
+  explicit SparcTTIImpl(const SparcTargetMachine *TM, const Function &F)
+      : BaseT(TM, F.getDataLayout()), ST(TM->getSubtargetImpl(F)),
+        TLI(ST->getTargetLowering()) {}
+
+  /// \name Scalar TTI Implementations
+  /// @{
+  InstructionCost getIntImmCost(const APInt &Imm, Type *Ty,
+                                TTI::TargetCostKind CostKind) const override;
+
+  InstructionCost getIntImmCostInst(unsigned Opcode, unsigned Idx,
+                                    const APInt &Imm, Type *Ty,
+                                    TTI::TargetCostKind CostKind,
+                                    Instruction *Inst = nullptr) const override;
+  InstructionCost
+  getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx, const APInt &Imm,
+                      Type *Ty, TTI::TargetCostKind CostKind) const override {
+    return getIntImmCost(Imm, Ty, CostKind);
+  };
+
+  TTI::PopcntSupportKind getPopcntSupport(unsigned TyWidth) const override;
+  /// @}
+
+  /// \name Vector TTI Implementations
+  /// @{
+  enum SparcRegisterClass { GPRRC, FPRRC, FP128RRC };
+  unsigned getNumberOfRegisters(unsigned ClassID) const override;
+  unsigned getRegisterClassForType(bool Vector,
+                                   Type *Ty = nullptr) const override;
+  TypeSize
+  getRegisterBitWidth(TargetTransformInfo::RegisterKind K) const override;
+  /// @}
+};
+
+} // end namespace llvm
+
+#endif

>From 90e204eb7cc889121f892442d30b9dd831d45559 Mon Sep 17 00:00:00 2001
From: Koakuma <koachan at protonmail.com>
Date: Thu, 29 Jan 2026 23:33:38 +0700
Subject: [PATCH 2/8] Make vector register amount to be zero

---
 llvm/lib/Target/Sparc/SparcTargetTransformInfo.cpp | 7 ++++++-
 llvm/lib/Target/Sparc/SparcTargetTransformInfo.h   | 2 +-
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/Sparc/SparcTargetTransformInfo.cpp b/llvm/lib/Target/Sparc/SparcTargetTransformInfo.cpp
index d0fe94fb6ff73..b1bf75d1c4899 100644
--- a/llvm/lib/Target/Sparc/SparcTargetTransformInfo.cpp
+++ b/llvm/lib/Target/Sparc/SparcTargetTransformInfo.cpp
@@ -66,7 +66,7 @@ SparcTTIImpl::getPopcntSupport(unsigned TyWidth) const {
 
 unsigned SparcTTIImpl::getRegisterClassForType(bool Vector, Type *Ty) const {
   if (Vector)
-    return FPRRC;
+    return VRRC;
   if (Ty &&
       (Ty->getScalarType()->isFloatTy() || Ty->getScalarType()->isDoubleTy()))
     return FPRRC;
@@ -85,6 +85,11 @@ unsigned SparcTTIImpl::getNumberOfRegisters(unsigned ClassID) const {
     return 32;
   case FP128RRC:
     return 16;
+  case VRRC:
+    // TODO We have vector capabilities as part of the VIS extensions, but the
+    // codegen doesn't currently use it. Revisit this when vector codegen is
+    // ready.
+    return 0;
   }
 
   llvm_unreachable("Unsupported register class");
diff --git a/llvm/lib/Target/Sparc/SparcTargetTransformInfo.h b/llvm/lib/Target/Sparc/SparcTargetTransformInfo.h
index 042fe498f2a76..0d1048c93f7ad 100644
--- a/llvm/lib/Target/Sparc/SparcTargetTransformInfo.h
+++ b/llvm/lib/Target/Sparc/SparcTargetTransformInfo.h
@@ -58,7 +58,7 @@ class SparcTTIImpl final : public BasicTTIImplBase<SparcTTIImpl> {
 
   /// \name Vector TTI Implementations
   /// @{
-  enum SparcRegisterClass { GPRRC, FPRRC, FP128RRC };
+  enum SparcRegisterClass { GPRRC, FPRRC, FP128RRC, VRRC };
   unsigned getNumberOfRegisters(unsigned ClassID) const override;
   unsigned getRegisterClassForType(bool Vector,
                                    Type *Ty = nullptr) const override;

>From 53965918721520fdc8f007962593ffb40508e48c Mon Sep 17 00:00:00 2001
From: Koakuma <koachan at protonmail.com>
Date: Fri, 30 Jan 2026 13:31:37 +0700
Subject: [PATCH 3/8] Add popcnt test

---
 .../test/Transforms/LoopIdiom/Sparc/popcnt.ll | 319 ++++++++++++++++++
 1 file changed, 319 insertions(+)
 create mode 100644 llvm/test/Transforms/LoopIdiom/Sparc/popcnt.ll

diff --git a/llvm/test/Transforms/LoopIdiom/Sparc/popcnt.ll b/llvm/test/Transforms/LoopIdiom/Sparc/popcnt.ll
new file mode 100644
index 0000000000000..d3a5f575c8f8a
--- /dev/null
+++ b/llvm/test/Transforms/LoopIdiom/Sparc/popcnt.ll
@@ -0,0 +1,319 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -passes=loop-idiom -mtriple=sparcv9 -mattr=+popc -S < %s | FileCheck %s --check-prefixes=SPARC64-CPOP
+; RUN: opt -passes=loop-idiom -mtriple=sparcv9 -S < %s | FileCheck %s --check-prefixes=SPARC64-NOCPOP
+
+; Mostly copied from AMDGPU version.
+
+;To recognize this pattern:
+;int popcount(unsigned long long a) {
+;    int c = 0;
+;    while (a) {
+;        c++;
+;        a &= a - 1;
+;    }
+;    return c;
+;}
+;
+
+define i32 @popcount_i64(i64 %a) nounwind uwtable readnone ssp {
+; SPARC64-CPOP-LABEL: @popcount_i64(
+; SPARC64-CPOP-NEXT:  entry:
+; SPARC64-CPOP-NEXT:    [[TMP0:%.*]] = call i64 @llvm.ctpop.i64(i64 [[A:%.*]])
+; SPARC64-CPOP-NEXT:    [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32
+; SPARC64-CPOP-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
+; SPARC64-CPOP-NEXT:    br i1 [[TMP2]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
+; SPARC64-CPOP:       while.body.preheader:
+; SPARC64-CPOP-NEXT:    br label [[WHILE_BODY:%.*]]
+; SPARC64-CPOP:       while.body:
+; SPARC64-CPOP-NEXT:    [[TCPHI:%.*]] = phi i32 [ [[TMP1]], [[WHILE_BODY_PREHEADER]] ], [ [[TCDEC:%.*]], [[WHILE_BODY]] ]
+; SPARC64-CPOP-NEXT:    [[C_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
+; SPARC64-CPOP-NEXT:    [[A_ADDR_04:%.*]] = phi i64 [ [[AND:%.*]], [[WHILE_BODY]] ], [ [[A]], [[WHILE_BODY_PREHEADER]] ]
+; SPARC64-CPOP-NEXT:    [[INC]] = add nsw i32 [[C_05]], 1
+; SPARC64-CPOP-NEXT:    [[SUB:%.*]] = add i64 [[A_ADDR_04]], -1
+; SPARC64-CPOP-NEXT:    [[AND]] = and i64 [[SUB]], [[A_ADDR_04]]
+; SPARC64-CPOP-NEXT:    [[TCDEC]] = sub nsw i32 [[TCPHI]], 1
+; SPARC64-CPOP-NEXT:    [[TOBOOL:%.*]] = icmp sle i32 [[TCDEC]], 0
+; SPARC64-CPOP-NEXT:    br i1 [[TOBOOL]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY]]
+; SPARC64-CPOP:       while.end.loopexit:
+; SPARC64-CPOP-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[TMP1]], [[WHILE_BODY]] ]
+; SPARC64-CPOP-NEXT:    br label [[WHILE_END]]
+; SPARC64-CPOP:       while.end:
+; SPARC64-CPOP-NEXT:    [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
+; SPARC64-CPOP-NEXT:    ret i32 [[C_0_LCSSA]]
+;
+; SPARC64-NOCPOP-LABEL: @popcount_i64(
+; SPARC64-NOCPOP-NEXT:  entry:
+; SPARC64-NOCPOP-NEXT:    [[TOBOOL3:%.*]] = icmp eq i64 [[A:%.*]], 0
+; SPARC64-NOCPOP-NEXT:    br i1 [[TOBOOL3]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
+; SPARC64-NOCPOP:       while.body.preheader:
+; SPARC64-NOCPOP-NEXT:    br label [[WHILE_BODY:%.*]]
+; SPARC64-NOCPOP:       while.body:
+; SPARC64-NOCPOP-NEXT:    [[C_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
+; SPARC64-NOCPOP-NEXT:    [[A_ADDR_04:%.*]] = phi i64 [ [[AND:%.*]], [[WHILE_BODY]] ], [ [[A]], [[WHILE_BODY_PREHEADER]] ]
+; SPARC64-NOCPOP-NEXT:    [[INC]] = add nsw i32 [[C_05]], 1
+; SPARC64-NOCPOP-NEXT:    [[SUB:%.*]] = add i64 [[A_ADDR_04]], -1
+; SPARC64-NOCPOP-NEXT:    [[AND]] = and i64 [[SUB]], [[A_ADDR_04]]
+; SPARC64-NOCPOP-NEXT:    [[TOBOOL:%.*]] = icmp eq i64 [[AND]], 0
+; SPARC64-NOCPOP-NEXT:    br i1 [[TOBOOL]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY]]
+; SPARC64-NOCPOP:       while.end.loopexit:
+; SPARC64-NOCPOP-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ]
+; SPARC64-NOCPOP-NEXT:    br label [[WHILE_END]]
+; SPARC64-NOCPOP:       while.end:
+; SPARC64-NOCPOP-NEXT:    [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
+; SPARC64-NOCPOP-NEXT:    ret i32 [[C_0_LCSSA]]
+;
+entry:
+  %tobool3 = icmp eq i64 %a, 0
+  br i1 %tobool3, label %while.end, label %while.body
+
+while.body:                                       ; preds = %entry, %while.body
+  %c.05 = phi i32 [ %inc, %while.body ], [ 0, %entry ]
+  %a.addr.04 = phi i64 [ %and, %while.body ], [ %a, %entry ]
+  %inc = add nsw i32 %c.05, 1
+  %sub = add i64 %a.addr.04, -1
+  %and = and i64 %sub, %a.addr.04
+  %tobool = icmp eq i64 %and, 0
+  br i1 %tobool, label %while.end, label %while.body
+
+while.end:                                        ; preds = %while.body, %entry
+  %c.0.lcssa = phi i32 [ 0, %entry ], [ %inc, %while.body ]
+  ret i32 %c.0.lcssa
+}
+
+define i32 @popcount_i32(i32 %a) nounwind uwtable readnone ssp {
+; SPARC64-CPOP-LABEL: @popcount_i32(
+; SPARC64-CPOP-NEXT:  entry:
+; SPARC64-CPOP-NEXT:    [[TMP0:%.*]] = call i32 @llvm.ctpop.i32(i32 [[A:%.*]])
+; SPARC64-CPOP-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 0
+; SPARC64-CPOP-NEXT:    br i1 [[TMP1]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
+; SPARC64-CPOP:       while.body.preheader:
+; SPARC64-CPOP-NEXT:    br label [[WHILE_BODY:%.*]]
+; SPARC64-CPOP:       while.body:
+; SPARC64-CPOP-NEXT:    [[TCPHI:%.*]] = phi i32 [ [[TMP0]], [[WHILE_BODY_PREHEADER]] ], [ [[TCDEC:%.*]], [[WHILE_BODY]] ]
+; SPARC64-CPOP-NEXT:    [[C_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
+; SPARC64-CPOP-NEXT:    [[A_ADDR_04:%.*]] = phi i32 [ [[AND:%.*]], [[WHILE_BODY]] ], [ [[A]], [[WHILE_BODY_PREHEADER]] ]
+; SPARC64-CPOP-NEXT:    [[INC]] = add nsw i32 [[C_05]], 1
+; SPARC64-CPOP-NEXT:    [[SUB:%.*]] = add i32 [[A_ADDR_04]], -1
+; SPARC64-CPOP-NEXT:    [[AND]] = and i32 [[SUB]], [[A_ADDR_04]]
+; SPARC64-CPOP-NEXT:    [[TCDEC]] = sub nsw i32 [[TCPHI]], 1
+; SPARC64-CPOP-NEXT:    [[TOBOOL:%.*]] = icmp sle i32 [[TCDEC]], 0
+; SPARC64-CPOP-NEXT:    br i1 [[TOBOOL]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY]]
+; SPARC64-CPOP:       while.end.loopexit:
+; SPARC64-CPOP-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[TMP0]], [[WHILE_BODY]] ]
+; SPARC64-CPOP-NEXT:    br label [[WHILE_END]]
+; SPARC64-CPOP:       while.end:
+; SPARC64-CPOP-NEXT:    [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
+; SPARC64-CPOP-NEXT:    ret i32 [[C_0_LCSSA]]
+;
+; SPARC64-NOCPOP-LABEL: @popcount_i32(
+; SPARC64-NOCPOP-NEXT:  entry:
+; SPARC64-NOCPOP-NEXT:    [[TOBOOL3:%.*]] = icmp eq i32 [[A:%.*]], 0
+; SPARC64-NOCPOP-NEXT:    br i1 [[TOBOOL3]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
+; SPARC64-NOCPOP:       while.body.preheader:
+; SPARC64-NOCPOP-NEXT:    br label [[WHILE_BODY:%.*]]
+; SPARC64-NOCPOP:       while.body:
+; SPARC64-NOCPOP-NEXT:    [[C_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
+; SPARC64-NOCPOP-NEXT:    [[A_ADDR_04:%.*]] = phi i32 [ [[AND:%.*]], [[WHILE_BODY]] ], [ [[A]], [[WHILE_BODY_PREHEADER]] ]
+; SPARC64-NOCPOP-NEXT:    [[INC]] = add nsw i32 [[C_05]], 1
+; SPARC64-NOCPOP-NEXT:    [[SUB:%.*]] = add i32 [[A_ADDR_04]], -1
+; SPARC64-NOCPOP-NEXT:    [[AND]] = and i32 [[SUB]], [[A_ADDR_04]]
+; SPARC64-NOCPOP-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[AND]], 0
+; SPARC64-NOCPOP-NEXT:    br i1 [[TOBOOL]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY]]
+; SPARC64-NOCPOP:       while.end.loopexit:
+; SPARC64-NOCPOP-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ]
+; SPARC64-NOCPOP-NEXT:    br label [[WHILE_END]]
+; SPARC64-NOCPOP:       while.end:
+; SPARC64-NOCPOP-NEXT:    [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
+; SPARC64-NOCPOP-NEXT:    ret i32 [[C_0_LCSSA]]
+;
+entry:
+  %tobool3 = icmp eq i32 %a, 0
+  br i1 %tobool3, label %while.end, label %while.body
+
+while.body:                                       ; preds = %entry, %while.body
+  %c.05 = phi i32 [ %inc, %while.body ], [ 0, %entry ]
+  %a.addr.04 = phi i32 [ %and, %while.body ], [ %a, %entry ]
+  %inc = add nsw i32 %c.05, 1
+  %sub = add i32 %a.addr.04, -1
+  %and = and i32 %sub, %a.addr.04
+  %tobool = icmp eq i32 %and, 0
+  br i1 %tobool, label %while.end, label %while.body
+
+while.end:                                        ; preds = %while.body, %entry
+  %c.0.lcssa = phi i32 [ 0, %entry ], [ %inc, %while.body ]
+  ret i32 %c.0.lcssa
+}
+
+define i32 @popcount_i128(i128 %a) nounwind uwtable readnone ssp {
+; SPARC64-CPOP-LABEL: @popcount_i128(
+; SPARC64-CPOP-NEXT:  entry:
+; SPARC64-CPOP-NEXT:    [[TMP0:%.*]] = call i128 @llvm.ctpop.i128(i128 [[A:%.*]])
+; SPARC64-CPOP-NEXT:    [[TMP1:%.*]] = trunc i128 [[TMP0]] to i32
+; SPARC64-CPOP-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
+; SPARC64-CPOP-NEXT:    br i1 [[TMP2]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
+; SPARC64-CPOP:       while.body.preheader:
+; SPARC64-CPOP-NEXT:    br label [[WHILE_BODY:%.*]]
+; SPARC64-CPOP:       while.body:
+; SPARC64-CPOP-NEXT:    [[TCPHI:%.*]] = phi i32 [ [[TMP1]], [[WHILE_BODY_PREHEADER]] ], [ [[TCDEC:%.*]], [[WHILE_BODY]] ]
+; SPARC64-CPOP-NEXT:    [[C_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
+; SPARC64-CPOP-NEXT:    [[A_ADDR_04:%.*]] = phi i128 [ [[AND:%.*]], [[WHILE_BODY]] ], [ [[A]], [[WHILE_BODY_PREHEADER]] ]
+; SPARC64-CPOP-NEXT:    [[INC]] = add nsw i32 [[C_05]], 1
+; SPARC64-CPOP-NEXT:    [[SUB:%.*]] = add i128 [[A_ADDR_04]], -1
+; SPARC64-CPOP-NEXT:    [[AND]] = and i128 [[SUB]], [[A_ADDR_04]]
+; SPARC64-CPOP-NEXT:    [[TCDEC]] = sub nsw i32 [[TCPHI]], 1
+; SPARC64-CPOP-NEXT:    [[TOBOOL:%.*]] = icmp sle i32 [[TCDEC]], 0
+; SPARC64-CPOP-NEXT:    br i1 [[TOBOOL]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY]]
+; SPARC64-CPOP:       while.end.loopexit:
+; SPARC64-CPOP-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[TMP1]], [[WHILE_BODY]] ]
+; SPARC64-CPOP-NEXT:    br label [[WHILE_END]]
+; SPARC64-CPOP:       while.end:
+; SPARC64-CPOP-NEXT:    [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
+; SPARC64-CPOP-NEXT:    ret i32 [[C_0_LCSSA]]
+;
+; SPARC64-NOCPOP-LABEL: @popcount_i128(
+; SPARC64-NOCPOP-NEXT:  entry:
+; SPARC64-NOCPOP-NEXT:    [[TOBOOL3:%.*]] = icmp eq i128 [[A:%.*]], 0
+; SPARC64-NOCPOP-NEXT:    br i1 [[TOBOOL3]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
+; SPARC64-NOCPOP:       while.body.preheader:
+; SPARC64-NOCPOP-NEXT:    br label [[WHILE_BODY:%.*]]
+; SPARC64-NOCPOP:       while.body:
+; SPARC64-NOCPOP-NEXT:    [[C_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
+; SPARC64-NOCPOP-NEXT:    [[A_ADDR_04:%.*]] = phi i128 [ [[AND:%.*]], [[WHILE_BODY]] ], [ [[A]], [[WHILE_BODY_PREHEADER]] ]
+; SPARC64-NOCPOP-NEXT:    [[INC]] = add nsw i32 [[C_05]], 1
+; SPARC64-NOCPOP-NEXT:    [[SUB:%.*]] = add i128 [[A_ADDR_04]], -1
+; SPARC64-NOCPOP-NEXT:    [[AND]] = and i128 [[SUB]], [[A_ADDR_04]]
+; SPARC64-NOCPOP-NEXT:    [[TOBOOL:%.*]] = icmp eq i128 [[AND]], 0
+; SPARC64-NOCPOP-NEXT:    br i1 [[TOBOOL]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY]]
+; SPARC64-NOCPOP:       while.end.loopexit:
+; SPARC64-NOCPOP-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ]
+; SPARC64-NOCPOP-NEXT:    br label [[WHILE_END]]
+; SPARC64-NOCPOP:       while.end:
+; SPARC64-NOCPOP-NEXT:    [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
+; SPARC64-NOCPOP-NEXT:    ret i32 [[C_0_LCSSA]]
+;
+entry:
+  %tobool3 = icmp eq i128 %a, 0
+  br i1 %tobool3, label %while.end, label %while.body
+
+while.body:                                       ; preds = %entry, %while.body
+  %c.05 = phi i32 [ %inc, %while.body ], [ 0, %entry ]
+  %a.addr.04 = phi i128 [ %and, %while.body ], [ %a, %entry ]
+  %inc = add nsw i32 %c.05, 1
+  %sub = add i128 %a.addr.04, -1
+  %and = and i128 %sub, %a.addr.04
+  %tobool = icmp eq i128 %and, 0
+  br i1 %tobool, label %while.end, label %while.body
+
+while.end:                                        ; preds = %while.body, %entry
+  %c.0.lcssa = phi i32 [ 0, %entry ], [ %inc, %while.body ]
+  ret i32 %c.0.lcssa
+}
+
+; To recognize this pattern:
+;int popcount(unsigned long long a, int mydata1, int mydata2) {
+;    int c = 0;
+;    while (a) {
+;        c++;
+;        a &= a - 1;
+;        mydata1 *= c;
+;        mydata2 *= (int)a;
+;    }
+;    return c + mydata1 + mydata2;
+;}
+
+define i32 @popcount2(i64 %a, i32 %mydata1, i32 %mydata2) nounwind uwtable readnone ssp {
+; SPARC64-CPOP-LABEL: @popcount2(
+; SPARC64-CPOP-NEXT:  entry:
+; SPARC64-CPOP-NEXT:    [[TMP0:%.*]] = call i64 @llvm.ctpop.i64(i64 [[A:%.*]])
+; SPARC64-CPOP-NEXT:    [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32
+; SPARC64-CPOP-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
+; SPARC64-CPOP-NEXT:    br i1 [[TMP2]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
+; SPARC64-CPOP:       while.body.preheader:
+; SPARC64-CPOP-NEXT:    br label [[WHILE_BODY:%.*]]
+; SPARC64-CPOP:       while.body:
+; SPARC64-CPOP-NEXT:    [[TCPHI:%.*]] = phi i32 [ [[TMP1]], [[WHILE_BODY_PREHEADER]] ], [ [[TCDEC:%.*]], [[WHILE_BODY]] ]
+; SPARC64-CPOP-NEXT:    [[C_013:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
+; SPARC64-CPOP-NEXT:    [[MYDATA2_ADDR_012:%.*]] = phi i32 [ [[MUL1:%.*]], [[WHILE_BODY]] ], [ [[MYDATA2:%.*]], [[WHILE_BODY_PREHEADER]] ]
+; SPARC64-CPOP-NEXT:    [[MYDATA1_ADDR_011:%.*]] = phi i32 [ [[MUL:%.*]], [[WHILE_BODY]] ], [ [[MYDATA1:%.*]], [[WHILE_BODY_PREHEADER]] ]
+; SPARC64-CPOP-NEXT:    [[A_ADDR_010:%.*]] = phi i64 [ [[AND:%.*]], [[WHILE_BODY]] ], [ [[A]], [[WHILE_BODY_PREHEADER]] ]
+; SPARC64-CPOP-NEXT:    [[INC]] = add nsw i32 [[C_013]], 1
+; SPARC64-CPOP-NEXT:    [[SUB:%.*]] = add i64 [[A_ADDR_010]], -1
+; SPARC64-CPOP-NEXT:    [[AND]] = and i64 [[SUB]], [[A_ADDR_010]]
+; SPARC64-CPOP-NEXT:    [[MUL]] = mul nsw i32 [[INC]], [[MYDATA1_ADDR_011]]
+; SPARC64-CPOP-NEXT:    [[CONV:%.*]] = trunc i64 [[AND]] to i32
+; SPARC64-CPOP-NEXT:    [[MUL1]] = mul nsw i32 [[CONV]], [[MYDATA2_ADDR_012]]
+; SPARC64-CPOP-NEXT:    [[TCDEC]] = sub nsw i32 [[TCPHI]], 1
+; SPARC64-CPOP-NEXT:    [[TOBOOL:%.*]] = icmp sle i32 [[TCDEC]], 0
+; SPARC64-CPOP-NEXT:    br i1 [[TOBOOL]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY]]
+; SPARC64-CPOP:       while.end.loopexit:
+; SPARC64-CPOP-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[TMP1]], [[WHILE_BODY]] ]
+; SPARC64-CPOP-NEXT:    [[MUL_LCSSA:%.*]] = phi i32 [ [[MUL]], [[WHILE_BODY]] ]
+; SPARC64-CPOP-NEXT:    [[MUL1_LCSSA:%.*]] = phi i32 [ [[MUL1]], [[WHILE_BODY]] ]
+; SPARC64-CPOP-NEXT:    br label [[WHILE_END]]
+; SPARC64-CPOP:       while.end:
+; SPARC64-CPOP-NEXT:    [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
+; SPARC64-CPOP-NEXT:    [[MYDATA2_ADDR_0_LCSSA:%.*]] = phi i32 [ [[MYDATA2]], [[ENTRY]] ], [ [[MUL1_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
+; SPARC64-CPOP-NEXT:    [[MYDATA1_ADDR_0_LCSSA:%.*]] = phi i32 [ [[MYDATA1]], [[ENTRY]] ], [ [[MUL_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
+; SPARC64-CPOP-NEXT:    [[ADD:%.*]] = add i32 [[MYDATA2_ADDR_0_LCSSA]], [[MYDATA1_ADDR_0_LCSSA]]
+; SPARC64-CPOP-NEXT:    [[ADD2:%.*]] = add i32 [[ADD]], [[C_0_LCSSA]]
+; SPARC64-CPOP-NEXT:    ret i32 [[ADD2]]
+;
+; SPARC64-NOCPOP-LABEL: @popcount2(
+; SPARC64-NOCPOP-NEXT:  entry:
+; SPARC64-NOCPOP-NEXT:    [[TOBOOL9:%.*]] = icmp eq i64 [[A:%.*]], 0
+; SPARC64-NOCPOP-NEXT:    br i1 [[TOBOOL9]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
+; SPARC64-NOCPOP:       while.body.preheader:
+; SPARC64-NOCPOP-NEXT:    br label [[WHILE_BODY:%.*]]
+; SPARC64-NOCPOP:       while.body:
+; SPARC64-NOCPOP-NEXT:    [[C_013:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
+; SPARC64-NOCPOP-NEXT:    [[MYDATA2_ADDR_012:%.*]] = phi i32 [ [[MUL1:%.*]], [[WHILE_BODY]] ], [ [[MYDATA2:%.*]], [[WHILE_BODY_PREHEADER]] ]
+; SPARC64-NOCPOP-NEXT:    [[MYDATA1_ADDR_011:%.*]] = phi i32 [ [[MUL:%.*]], [[WHILE_BODY]] ], [ [[MYDATA1:%.*]], [[WHILE_BODY_PREHEADER]] ]
+; SPARC64-NOCPOP-NEXT:    [[A_ADDR_010:%.*]] = phi i64 [ [[AND:%.*]], [[WHILE_BODY]] ], [ [[A]], [[WHILE_BODY_PREHEADER]] ]
+; SPARC64-NOCPOP-NEXT:    [[INC]] = add nsw i32 [[C_013]], 1
+; SPARC64-NOCPOP-NEXT:    [[SUB:%.*]] = add i64 [[A_ADDR_010]], -1
+; SPARC64-NOCPOP-NEXT:    [[AND]] = and i64 [[SUB]], [[A_ADDR_010]]
+; SPARC64-NOCPOP-NEXT:    [[MUL]] = mul nsw i32 [[INC]], [[MYDATA1_ADDR_011]]
+; SPARC64-NOCPOP-NEXT:    [[CONV:%.*]] = trunc i64 [[AND]] to i32
+; SPARC64-NOCPOP-NEXT:    [[MUL1]] = mul nsw i32 [[CONV]], [[MYDATA2_ADDR_012]]
+; SPARC64-NOCPOP-NEXT:    [[TOBOOL:%.*]] = icmp eq i64 [[AND]], 0
+; SPARC64-NOCPOP-NEXT:    br i1 [[TOBOOL]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY]]
+; SPARC64-NOCPOP:       while.end.loopexit:
+; SPARC64-NOCPOP-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ]
+; SPARC64-NOCPOP-NEXT:    [[MUL_LCSSA:%.*]] = phi i32 [ [[MUL]], [[WHILE_BODY]] ]
+; SPARC64-NOCPOP-NEXT:    [[MUL1_LCSSA:%.*]] = phi i32 [ [[MUL1]], [[WHILE_BODY]] ]
+; SPARC64-NOCPOP-NEXT:    br label [[WHILE_END]]
+; SPARC64-NOCPOP:       while.end:
+; SPARC64-NOCPOP-NEXT:    [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
+; SPARC64-NOCPOP-NEXT:    [[MYDATA2_ADDR_0_LCSSA:%.*]] = phi i32 [ [[MYDATA2]], [[ENTRY]] ], [ [[MUL1_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
+; SPARC64-NOCPOP-NEXT:    [[MYDATA1_ADDR_0_LCSSA:%.*]] = phi i32 [ [[MYDATA1]], [[ENTRY]] ], [ [[MUL_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
+; SPARC64-NOCPOP-NEXT:    [[ADD:%.*]] = add i32 [[MYDATA2_ADDR_0_LCSSA]], [[MYDATA1_ADDR_0_LCSSA]]
+; SPARC64-NOCPOP-NEXT:    [[ADD2:%.*]] = add i32 [[ADD]], [[C_0_LCSSA]]
+; SPARC64-NOCPOP-NEXT:    ret i32 [[ADD2]]
+;
+entry:
+  %tobool9 = icmp eq i64 %a, 0
+  br i1 %tobool9, label %while.end, label %while.body
+
+while.body:                                       ; preds = %entry, %while.body
+  %c.013 = phi i32 [ %inc, %while.body ], [ 0, %entry ]
+  %mydata2.addr.012 = phi i32 [ %mul1, %while.body ], [ %mydata2, %entry ]
+  %mydata1.addr.011 = phi i32 [ %mul, %while.body ], [ %mydata1, %entry ]
+  %a.addr.010 = phi i64 [ %and, %while.body ], [ %a, %entry ]
+  %inc = add nsw i32 %c.013, 1
+  %sub = add i64 %a.addr.010, -1
+  %and = and i64 %sub, %a.addr.010
+  %mul = mul nsw i32 %inc, %mydata1.addr.011
+  %conv = trunc i64 %and to i32
+  %mul1 = mul nsw i32 %conv, %mydata2.addr.012
+  %tobool = icmp eq i64 %and, 0
+  br i1 %tobool, label %while.end, label %while.body
+
+while.end:                                        ; preds = %while.body, %entry
+  %c.0.lcssa = phi i32 [ 0, %entry ], [ %inc, %while.body ]
+  %mydata2.addr.0.lcssa = phi i32 [ %mydata2, %entry ], [ %mul1, %while.body ]
+  %mydata1.addr.0.lcssa = phi i32 [ %mydata1, %entry ], [ %mul, %while.body ]
+  %add = add i32 %mydata2.addr.0.lcssa, %mydata1.addr.0.lcssa
+  %add2 = add i32 %add, %c.0.lcssa
+  ret i32 %add2
+}
+

>From 06e4b7453d2cf2857c3585ba663bdba12eeeadac Mon Sep 17 00:00:00 2001
From: Koakuma <koachan at protonmail.com>
Date: Fri, 30 Jan 2026 13:46:11 +0700
Subject: [PATCH 4/8] Add sparc32 popcnt test

---
 .../test/Transforms/LoopIdiom/Sparc/popcnt.ll | 192 ++++++++++++++++++
 1 file changed, 192 insertions(+)

diff --git a/llvm/test/Transforms/LoopIdiom/Sparc/popcnt.ll b/llvm/test/Transforms/LoopIdiom/Sparc/popcnt.ll
index d3a5f575c8f8a..3d4a86db1c3fc 100644
--- a/llvm/test/Transforms/LoopIdiom/Sparc/popcnt.ll
+++ b/llvm/test/Transforms/LoopIdiom/Sparc/popcnt.ll
@@ -1,5 +1,7 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -passes=loop-idiom -mtriple=sparc -mattr=+popc -S < %s | FileCheck %s --check-prefixes=SPARC-CPOP
 ; RUN: opt -passes=loop-idiom -mtriple=sparcv9 -mattr=+popc -S < %s | FileCheck %s --check-prefixes=SPARC64-CPOP
+; RUN: opt -passes=loop-idiom -mtriple=sparc -S < %s | FileCheck %s --check-prefixes=SPARC-NOCPOP
 ; RUN: opt -passes=loop-idiom -mtriple=sparcv9 -S < %s | FileCheck %s --check-prefixes=SPARC64-NOCPOP
 
 ; Mostly copied from AMDGPU version.
@@ -16,6 +18,27 @@
 ;
 
 define i32 @popcount_i64(i64 %a) nounwind uwtable readnone ssp {
+; SPARC-CPOP-LABEL: @popcount_i64(
+; SPARC-CPOP-NEXT:  entry:
+; SPARC-CPOP-NEXT:    [[TOBOOL3:%.*]] = icmp eq i64 [[A:%.*]], 0
+; SPARC-CPOP-NEXT:    br i1 [[TOBOOL3]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
+; SPARC-CPOP:       while.body.preheader:
+; SPARC-CPOP-NEXT:    br label [[WHILE_BODY:%.*]]
+; SPARC-CPOP:       while.body:
+; SPARC-CPOP-NEXT:    [[C_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
+; SPARC-CPOP-NEXT:    [[A_ADDR_04:%.*]] = phi i64 [ [[AND:%.*]], [[WHILE_BODY]] ], [ [[A]], [[WHILE_BODY_PREHEADER]] ]
+; SPARC-CPOP-NEXT:    [[INC]] = add nsw i32 [[C_05]], 1
+; SPARC-CPOP-NEXT:    [[SUB:%.*]] = add i64 [[A_ADDR_04]], -1
+; SPARC-CPOP-NEXT:    [[AND]] = and i64 [[SUB]], [[A_ADDR_04]]
+; SPARC-CPOP-NEXT:    [[TOBOOL:%.*]] = icmp eq i64 [[AND]], 0
+; SPARC-CPOP-NEXT:    br i1 [[TOBOOL]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY]]
+; SPARC-CPOP:       while.end.loopexit:
+; SPARC-CPOP-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ]
+; SPARC-CPOP-NEXT:    br label [[WHILE_END]]
+; SPARC-CPOP:       while.end:
+; SPARC-CPOP-NEXT:    [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
+; SPARC-CPOP-NEXT:    ret i32 [[C_0_LCSSA]]
+;
 ; SPARC64-CPOP-LABEL: @popcount_i64(
 ; SPARC64-CPOP-NEXT:  entry:
 ; SPARC64-CPOP-NEXT:    [[TMP0:%.*]] = call i64 @llvm.ctpop.i64(i64 [[A:%.*]])
@@ -41,6 +64,27 @@ define i32 @popcount_i64(i64 %a) nounwind uwtable readnone ssp {
 ; SPARC64-CPOP-NEXT:    [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
 ; SPARC64-CPOP-NEXT:    ret i32 [[C_0_LCSSA]]
 ;
+; SPARC-NOCPOP-LABEL: @popcount_i64(
+; SPARC-NOCPOP-NEXT:  entry:
+; SPARC-NOCPOP-NEXT:    [[TOBOOL3:%.*]] = icmp eq i64 [[A:%.*]], 0
+; SPARC-NOCPOP-NEXT:    br i1 [[TOBOOL3]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
+; SPARC-NOCPOP:       while.body.preheader:
+; SPARC-NOCPOP-NEXT:    br label [[WHILE_BODY:%.*]]
+; SPARC-NOCPOP:       while.body:
+; SPARC-NOCPOP-NEXT:    [[C_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
+; SPARC-NOCPOP-NEXT:    [[A_ADDR_04:%.*]] = phi i64 [ [[AND:%.*]], [[WHILE_BODY]] ], [ [[A]], [[WHILE_BODY_PREHEADER]] ]
+; SPARC-NOCPOP-NEXT:    [[INC]] = add nsw i32 [[C_05]], 1
+; SPARC-NOCPOP-NEXT:    [[SUB:%.*]] = add i64 [[A_ADDR_04]], -1
+; SPARC-NOCPOP-NEXT:    [[AND]] = and i64 [[SUB]], [[A_ADDR_04]]
+; SPARC-NOCPOP-NEXT:    [[TOBOOL:%.*]] = icmp eq i64 [[AND]], 0
+; SPARC-NOCPOP-NEXT:    br i1 [[TOBOOL]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY]]
+; SPARC-NOCPOP:       while.end.loopexit:
+; SPARC-NOCPOP-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ]
+; SPARC-NOCPOP-NEXT:    br label [[WHILE_END]]
+; SPARC-NOCPOP:       while.end:
+; SPARC-NOCPOP-NEXT:    [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
+; SPARC-NOCPOP-NEXT:    ret i32 [[C_0_LCSSA]]
+;
 ; SPARC64-NOCPOP-LABEL: @popcount_i64(
 ; SPARC64-NOCPOP-NEXT:  entry:
 ; SPARC64-NOCPOP-NEXT:    [[TOBOOL3:%.*]] = icmp eq i64 [[A:%.*]], 0
@@ -81,6 +125,27 @@ while.end:                                        ; preds = %while.body, %entry
 }
 
 define i32 @popcount_i32(i32 %a) nounwind uwtable readnone ssp {
+; SPARC-CPOP-LABEL: @popcount_i32(
+; SPARC-CPOP-NEXT:  entry:
+; SPARC-CPOP-NEXT:    [[TOBOOL3:%.*]] = icmp eq i32 [[A:%.*]], 0
+; SPARC-CPOP-NEXT:    br i1 [[TOBOOL3]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
+; SPARC-CPOP:       while.body.preheader:
+; SPARC-CPOP-NEXT:    br label [[WHILE_BODY:%.*]]
+; SPARC-CPOP:       while.body:
+; SPARC-CPOP-NEXT:    [[C_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
+; SPARC-CPOP-NEXT:    [[A_ADDR_04:%.*]] = phi i32 [ [[AND:%.*]], [[WHILE_BODY]] ], [ [[A]], [[WHILE_BODY_PREHEADER]] ]
+; SPARC-CPOP-NEXT:    [[INC]] = add nsw i32 [[C_05]], 1
+; SPARC-CPOP-NEXT:    [[SUB:%.*]] = add i32 [[A_ADDR_04]], -1
+; SPARC-CPOP-NEXT:    [[AND]] = and i32 [[SUB]], [[A_ADDR_04]]
+; SPARC-CPOP-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[AND]], 0
+; SPARC-CPOP-NEXT:    br i1 [[TOBOOL]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY]]
+; SPARC-CPOP:       while.end.loopexit:
+; SPARC-CPOP-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ]
+; SPARC-CPOP-NEXT:    br label [[WHILE_END]]
+; SPARC-CPOP:       while.end:
+; SPARC-CPOP-NEXT:    [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
+; SPARC-CPOP-NEXT:    ret i32 [[C_0_LCSSA]]
+;
 ; SPARC64-CPOP-LABEL: @popcount_i32(
 ; SPARC64-CPOP-NEXT:  entry:
 ; SPARC64-CPOP-NEXT:    [[TMP0:%.*]] = call i32 @llvm.ctpop.i32(i32 [[A:%.*]])
@@ -105,6 +170,27 @@ define i32 @popcount_i32(i32 %a) nounwind uwtable readnone ssp {
 ; SPARC64-CPOP-NEXT:    [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
 ; SPARC64-CPOP-NEXT:    ret i32 [[C_0_LCSSA]]
 ;
+; SPARC-NOCPOP-LABEL: @popcount_i32(
+; SPARC-NOCPOP-NEXT:  entry:
+; SPARC-NOCPOP-NEXT:    [[TOBOOL3:%.*]] = icmp eq i32 [[A:%.*]], 0
+; SPARC-NOCPOP-NEXT:    br i1 [[TOBOOL3]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
+; SPARC-NOCPOP:       while.body.preheader:
+; SPARC-NOCPOP-NEXT:    br label [[WHILE_BODY:%.*]]
+; SPARC-NOCPOP:       while.body:
+; SPARC-NOCPOP-NEXT:    [[C_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
+; SPARC-NOCPOP-NEXT:    [[A_ADDR_04:%.*]] = phi i32 [ [[AND:%.*]], [[WHILE_BODY]] ], [ [[A]], [[WHILE_BODY_PREHEADER]] ]
+; SPARC-NOCPOP-NEXT:    [[INC]] = add nsw i32 [[C_05]], 1
+; SPARC-NOCPOP-NEXT:    [[SUB:%.*]] = add i32 [[A_ADDR_04]], -1
+; SPARC-NOCPOP-NEXT:    [[AND]] = and i32 [[SUB]], [[A_ADDR_04]]
+; SPARC-NOCPOP-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[AND]], 0
+; SPARC-NOCPOP-NEXT:    br i1 [[TOBOOL]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY]]
+; SPARC-NOCPOP:       while.end.loopexit:
+; SPARC-NOCPOP-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ]
+; SPARC-NOCPOP-NEXT:    br label [[WHILE_END]]
+; SPARC-NOCPOP:       while.end:
+; SPARC-NOCPOP-NEXT:    [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
+; SPARC-NOCPOP-NEXT:    ret i32 [[C_0_LCSSA]]
+;
 ; SPARC64-NOCPOP-LABEL: @popcount_i32(
 ; SPARC64-NOCPOP-NEXT:  entry:
 ; SPARC64-NOCPOP-NEXT:    [[TOBOOL3:%.*]] = icmp eq i32 [[A:%.*]], 0
@@ -145,6 +231,27 @@ while.end:                                        ; preds = %while.body, %entry
 }
 
 define i32 @popcount_i128(i128 %a) nounwind uwtable readnone ssp {
+; SPARC-CPOP-LABEL: @popcount_i128(
+; SPARC-CPOP-NEXT:  entry:
+; SPARC-CPOP-NEXT:    [[TOBOOL3:%.*]] = icmp eq i128 [[A:%.*]], 0
+; SPARC-CPOP-NEXT:    br i1 [[TOBOOL3]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
+; SPARC-CPOP:       while.body.preheader:
+; SPARC-CPOP-NEXT:    br label [[WHILE_BODY:%.*]]
+; SPARC-CPOP:       while.body:
+; SPARC-CPOP-NEXT:    [[C_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
+; SPARC-CPOP-NEXT:    [[A_ADDR_04:%.*]] = phi i128 [ [[AND:%.*]], [[WHILE_BODY]] ], [ [[A]], [[WHILE_BODY_PREHEADER]] ]
+; SPARC-CPOP-NEXT:    [[INC]] = add nsw i32 [[C_05]], 1
+; SPARC-CPOP-NEXT:    [[SUB:%.*]] = add i128 [[A_ADDR_04]], -1
+; SPARC-CPOP-NEXT:    [[AND]] = and i128 [[SUB]], [[A_ADDR_04]]
+; SPARC-CPOP-NEXT:    [[TOBOOL:%.*]] = icmp eq i128 [[AND]], 0
+; SPARC-CPOP-NEXT:    br i1 [[TOBOOL]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY]]
+; SPARC-CPOP:       while.end.loopexit:
+; SPARC-CPOP-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ]
+; SPARC-CPOP-NEXT:    br label [[WHILE_END]]
+; SPARC-CPOP:       while.end:
+; SPARC-CPOP-NEXT:    [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
+; SPARC-CPOP-NEXT:    ret i32 [[C_0_LCSSA]]
+;
 ; SPARC64-CPOP-LABEL: @popcount_i128(
 ; SPARC64-CPOP-NEXT:  entry:
 ; SPARC64-CPOP-NEXT:    [[TMP0:%.*]] = call i128 @llvm.ctpop.i128(i128 [[A:%.*]])
@@ -170,6 +277,27 @@ define i32 @popcount_i128(i128 %a) nounwind uwtable readnone ssp {
 ; SPARC64-CPOP-NEXT:    [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
 ; SPARC64-CPOP-NEXT:    ret i32 [[C_0_LCSSA]]
 ;
+; SPARC-NOCPOP-LABEL: @popcount_i128(
+; SPARC-NOCPOP-NEXT:  entry:
+; SPARC-NOCPOP-NEXT:    [[TOBOOL3:%.*]] = icmp eq i128 [[A:%.*]], 0
+; SPARC-NOCPOP-NEXT:    br i1 [[TOBOOL3]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
+; SPARC-NOCPOP:       while.body.preheader:
+; SPARC-NOCPOP-NEXT:    br label [[WHILE_BODY:%.*]]
+; SPARC-NOCPOP:       while.body:
+; SPARC-NOCPOP-NEXT:    [[C_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
+; SPARC-NOCPOP-NEXT:    [[A_ADDR_04:%.*]] = phi i128 [ [[AND:%.*]], [[WHILE_BODY]] ], [ [[A]], [[WHILE_BODY_PREHEADER]] ]
+; SPARC-NOCPOP-NEXT:    [[INC]] = add nsw i32 [[C_05]], 1
+; SPARC-NOCPOP-NEXT:    [[SUB:%.*]] = add i128 [[A_ADDR_04]], -1
+; SPARC-NOCPOP-NEXT:    [[AND]] = and i128 [[SUB]], [[A_ADDR_04]]
+; SPARC-NOCPOP-NEXT:    [[TOBOOL:%.*]] = icmp eq i128 [[AND]], 0
+; SPARC-NOCPOP-NEXT:    br i1 [[TOBOOL]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY]]
+; SPARC-NOCPOP:       while.end.loopexit:
+; SPARC-NOCPOP-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ]
+; SPARC-NOCPOP-NEXT:    br label [[WHILE_END]]
+; SPARC-NOCPOP:       while.end:
+; SPARC-NOCPOP-NEXT:    [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
+; SPARC-NOCPOP-NEXT:    ret i32 [[C_0_LCSSA]]
+;
 ; SPARC64-NOCPOP-LABEL: @popcount_i128(
 ; SPARC64-NOCPOP-NEXT:  entry:
 ; SPARC64-NOCPOP-NEXT:    [[TOBOOL3:%.*]] = icmp eq i128 [[A:%.*]], 0
@@ -222,6 +350,38 @@ while.end:                                        ; preds = %while.body, %entry
 ;}
 
 define i32 @popcount2(i64 %a, i32 %mydata1, i32 %mydata2) nounwind uwtable readnone ssp {
+; SPARC-CPOP-LABEL: @popcount2(
+; SPARC-CPOP-NEXT:  entry:
+; SPARC-CPOP-NEXT:    [[TOBOOL9:%.*]] = icmp eq i64 [[A:%.*]], 0
+; SPARC-CPOP-NEXT:    br i1 [[TOBOOL9]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
+; SPARC-CPOP:       while.body.preheader:
+; SPARC-CPOP-NEXT:    br label [[WHILE_BODY:%.*]]
+; SPARC-CPOP:       while.body:
+; SPARC-CPOP-NEXT:    [[C_013:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
+; SPARC-CPOP-NEXT:    [[MYDATA2_ADDR_012:%.*]] = phi i32 [ [[MUL1:%.*]], [[WHILE_BODY]] ], [ [[MYDATA2:%.*]], [[WHILE_BODY_PREHEADER]] ]
+; SPARC-CPOP-NEXT:    [[MYDATA1_ADDR_011:%.*]] = phi i32 [ [[MUL:%.*]], [[WHILE_BODY]] ], [ [[MYDATA1:%.*]], [[WHILE_BODY_PREHEADER]] ]
+; SPARC-CPOP-NEXT:    [[A_ADDR_010:%.*]] = phi i64 [ [[AND:%.*]], [[WHILE_BODY]] ], [ [[A]], [[WHILE_BODY_PREHEADER]] ]
+; SPARC-CPOP-NEXT:    [[INC]] = add nsw i32 [[C_013]], 1
+; SPARC-CPOP-NEXT:    [[SUB:%.*]] = add i64 [[A_ADDR_010]], -1
+; SPARC-CPOP-NEXT:    [[AND]] = and i64 [[SUB]], [[A_ADDR_010]]
+; SPARC-CPOP-NEXT:    [[MUL]] = mul nsw i32 [[INC]], [[MYDATA1_ADDR_011]]
+; SPARC-CPOP-NEXT:    [[CONV:%.*]] = trunc i64 [[AND]] to i32
+; SPARC-CPOP-NEXT:    [[MUL1]] = mul nsw i32 [[CONV]], [[MYDATA2_ADDR_012]]
+; SPARC-CPOP-NEXT:    [[TOBOOL:%.*]] = icmp eq i64 [[AND]], 0
+; SPARC-CPOP-NEXT:    br i1 [[TOBOOL]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY]]
+; SPARC-CPOP:       while.end.loopexit:
+; SPARC-CPOP-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ]
+; SPARC-CPOP-NEXT:    [[MUL_LCSSA:%.*]] = phi i32 [ [[MUL]], [[WHILE_BODY]] ]
+; SPARC-CPOP-NEXT:    [[MUL1_LCSSA:%.*]] = phi i32 [ [[MUL1]], [[WHILE_BODY]] ]
+; SPARC-CPOP-NEXT:    br label [[WHILE_END]]
+; SPARC-CPOP:       while.end:
+; SPARC-CPOP-NEXT:    [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
+; SPARC-CPOP-NEXT:    [[MYDATA2_ADDR_0_LCSSA:%.*]] = phi i32 [ [[MYDATA2]], [[ENTRY]] ], [ [[MUL1_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
+; SPARC-CPOP-NEXT:    [[MYDATA1_ADDR_0_LCSSA:%.*]] = phi i32 [ [[MYDATA1]], [[ENTRY]] ], [ [[MUL_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
+; SPARC-CPOP-NEXT:    [[ADD:%.*]] = add i32 [[MYDATA2_ADDR_0_LCSSA]], [[MYDATA1_ADDR_0_LCSSA]]
+; SPARC-CPOP-NEXT:    [[ADD2:%.*]] = add i32 [[ADD]], [[C_0_LCSSA]]
+; SPARC-CPOP-NEXT:    ret i32 [[ADD2]]
+;
 ; SPARC64-CPOP-LABEL: @popcount2(
 ; SPARC64-CPOP-NEXT:  entry:
 ; SPARC64-CPOP-NEXT:    [[TMP0:%.*]] = call i64 @llvm.ctpop.i64(i64 [[A:%.*]])
@@ -258,6 +418,38 @@ define i32 @popcount2(i64 %a, i32 %mydata1, i32 %mydata2) nounwind uwtable readn
 ; SPARC64-CPOP-NEXT:    [[ADD2:%.*]] = add i32 [[ADD]], [[C_0_LCSSA]]
 ; SPARC64-CPOP-NEXT:    ret i32 [[ADD2]]
 ;
+; SPARC-NOCPOP-LABEL: @popcount2(
+; SPARC-NOCPOP-NEXT:  entry:
+; SPARC-NOCPOP-NEXT:    [[TOBOOL9:%.*]] = icmp eq i64 [[A:%.*]], 0
+; SPARC-NOCPOP-NEXT:    br i1 [[TOBOOL9]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
+; SPARC-NOCPOP:       while.body.preheader:
+; SPARC-NOCPOP-NEXT:    br label [[WHILE_BODY:%.*]]
+; SPARC-NOCPOP:       while.body:
+; SPARC-NOCPOP-NEXT:    [[C_013:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
+; SPARC-NOCPOP-NEXT:    [[MYDATA2_ADDR_012:%.*]] = phi i32 [ [[MUL1:%.*]], [[WHILE_BODY]] ], [ [[MYDATA2:%.*]], [[WHILE_BODY_PREHEADER]] ]
+; SPARC-NOCPOP-NEXT:    [[MYDATA1_ADDR_011:%.*]] = phi i32 [ [[MUL:%.*]], [[WHILE_BODY]] ], [ [[MYDATA1:%.*]], [[WHILE_BODY_PREHEADER]] ]
+; SPARC-NOCPOP-NEXT:    [[A_ADDR_010:%.*]] = phi i64 [ [[AND:%.*]], [[WHILE_BODY]] ], [ [[A]], [[WHILE_BODY_PREHEADER]] ]
+; SPARC-NOCPOP-NEXT:    [[INC]] = add nsw i32 [[C_013]], 1
+; SPARC-NOCPOP-NEXT:    [[SUB:%.*]] = add i64 [[A_ADDR_010]], -1
+; SPARC-NOCPOP-NEXT:    [[AND]] = and i64 [[SUB]], [[A_ADDR_010]]
+; SPARC-NOCPOP-NEXT:    [[MUL]] = mul nsw i32 [[INC]], [[MYDATA1_ADDR_011]]
+; SPARC-NOCPOP-NEXT:    [[CONV:%.*]] = trunc i64 [[AND]] to i32
+; SPARC-NOCPOP-NEXT:    [[MUL1]] = mul nsw i32 [[CONV]], [[MYDATA2_ADDR_012]]
+; SPARC-NOCPOP-NEXT:    [[TOBOOL:%.*]] = icmp eq i64 [[AND]], 0
+; SPARC-NOCPOP-NEXT:    br i1 [[TOBOOL]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY]]
+; SPARC-NOCPOP:       while.end.loopexit:
+; SPARC-NOCPOP-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ]
+; SPARC-NOCPOP-NEXT:    [[MUL_LCSSA:%.*]] = phi i32 [ [[MUL]], [[WHILE_BODY]] ]
+; SPARC-NOCPOP-NEXT:    [[MUL1_LCSSA:%.*]] = phi i32 [ [[MUL1]], [[WHILE_BODY]] ]
+; SPARC-NOCPOP-NEXT:    br label [[WHILE_END]]
+; SPARC-NOCPOP:       while.end:
+; SPARC-NOCPOP-NEXT:    [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
+; SPARC-NOCPOP-NEXT:    [[MYDATA2_ADDR_0_LCSSA:%.*]] = phi i32 [ [[MYDATA2]], [[ENTRY]] ], [ [[MUL1_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
+; SPARC-NOCPOP-NEXT:    [[MYDATA1_ADDR_0_LCSSA:%.*]] = phi i32 [ [[MYDATA1]], [[ENTRY]] ], [ [[MUL_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
+; SPARC-NOCPOP-NEXT:    [[ADD:%.*]] = add i32 [[MYDATA2_ADDR_0_LCSSA]], [[MYDATA1_ADDR_0_LCSSA]]
+; SPARC-NOCPOP-NEXT:    [[ADD2:%.*]] = add i32 [[ADD]], [[C_0_LCSSA]]
+; SPARC-NOCPOP-NEXT:    ret i32 [[ADD2]]
+;
 ; SPARC64-NOCPOP-LABEL: @popcount2(
 ; SPARC64-NOCPOP-NEXT:  entry:
 ; SPARC64-NOCPOP-NEXT:    [[TOBOOL9:%.*]] = icmp eq i64 [[A:%.*]], 0

>From 6d20706ade00a2a9747b8921cdc29e95d5c95ee5 Mon Sep 17 00:00:00 2001
From: Koakuma <koachan at protonmail.com>
Date: Fri, 30 Jan 2026 23:44:45 +0700
Subject: [PATCH 5/8] Add lit config

---
 llvm/test/Transforms/LoopIdiom/Sparc/lit.local.cfg | 2 ++
 1 file changed, 2 insertions(+)
 create mode 100644 llvm/test/Transforms/LoopIdiom/Sparc/lit.local.cfg

diff --git a/llvm/test/Transforms/LoopIdiom/Sparc/lit.local.cfg b/llvm/test/Transforms/LoopIdiom/Sparc/lit.local.cfg
new file mode 100644
index 0000000000000..4f5128663c5ac
--- /dev/null
+++ b/llvm/test/Transforms/LoopIdiom/Sparc/lit.local.cfg
@@ -0,0 +1,2 @@
+if not "Sparc" in config.root.targets:
+    config.unsupported = True

>From 468883059ddeef3a8570f8d083737c8356c616da Mon Sep 17 00:00:00 2001
From: Koakuma <koachan at protonmail.com>
Date: Sat, 31 Jan 2026 08:37:23 +0700
Subject: [PATCH 6/8] Only include the popcount part here

---
 .../Target/Sparc/SparcTargetTransformInfo.cpp | 92 -------------------
 .../Target/Sparc/SparcTargetTransformInfo.h   | 22 -----
 2 files changed, 114 deletions(-)

diff --git a/llvm/lib/Target/Sparc/SparcTargetTransformInfo.cpp b/llvm/lib/Target/Sparc/SparcTargetTransformInfo.cpp
index b1bf75d1c4899..cd8167eb742b7 100644
--- a/llvm/lib/Target/Sparc/SparcTargetTransformInfo.cpp
+++ b/llvm/lib/Target/Sparc/SparcTargetTransformInfo.cpp
@@ -13,49 +13,6 @@ using namespace llvm;
 
 #define DEBUG_TYPE "sparctti"
 
-InstructionCost
-SparcTTIImpl::getIntImmCost(const APInt &Imm, Type *Ty,
-                            TTI::TargetCostKind CostKind) const {
-  assert(Ty->isIntegerTy());
-  unsigned BitSize = Ty->getPrimitiveSizeInBits();
-
-  if (BitSize <= 64) {
-    // Small constants can be folded into instruction's immediate field.
-    if (isInt<13>(Imm.getSExtValue()))
-      return TTI::TCC_Free;
-
-    // Medium constants loaded via set.
-    if (isUInt<32>(Imm.getZExtValue()))
-      return TTI::TCC_Basic;
-
-    // Large constants loaded via setx on 64-bit targets.
-    if (ST->is64Bit())
-      return 3 * TTI::TCC_Basic;
-  }
-
-  // Very large constants load from constant pool.
-  return TTI::TCC_Expensive;
-}
-
-InstructionCost SparcTTIImpl::getIntImmCostInst(unsigned Opcode, unsigned Idx,
-                                                const APInt &Imm, Type *Ty,
-                                                TTI::TargetCostKind CostKind,
-                                                Instruction *Inst) const {
-  assert(Ty->isIntegerTy());
-
-  switch (Opcode) {
-  case Instruction::Shl:
-  case Instruction::LShr:
-  case Instruction::AShr:
-    // Always return TCC_Free for the shift value of a shift instruction.
-    return (Idx == 1) ? TTI::TCC_Free : TTI::TCC_Basic;
-  }
-
-  // All other instructions have the same 13-bit immediate field so we can just
-  // pass it here.
-  return getIntImmCost(Imm, Ty, CostKind);
-}
-
 TargetTransformInfo::PopcntSupportKind
 SparcTTIImpl::getPopcntSupport(unsigned TyWidth) const {
   assert(isPowerOf2_32(TyWidth) && "Type width must be power of 2");
@@ -63,52 +20,3 @@ SparcTTIImpl::getPopcntSupport(unsigned TyWidth) const {
     return TTI::PSK_FastHardware;
   return TTI::PSK_Software;
 }
-
-unsigned SparcTTIImpl::getRegisterClassForType(bool Vector, Type *Ty) const {
-  if (Vector)
-    return VRRC;
-  if (Ty &&
-      (Ty->getScalarType()->isFloatTy() || Ty->getScalarType()->isDoubleTy()))
-    return FPRRC;
-  if (Ty && (Ty->getScalarType()->isFP128Ty()))
-    return FP128RRC;
-  return GPRRC;
-}
-
-unsigned SparcTTIImpl::getNumberOfRegisters(unsigned ClassID) const {
-  switch (ClassID) {
-  case GPRRC:
-    // %g0, %g6, %g7, %o6, %i6, and %i7 are used for special purposes so we
-    // discount them here.
-    return 26;
-  case FPRRC:
-    return 32;
-  case FP128RRC:
-    return 16;
-  case VRRC:
-    // TODO We have vector capabilities as part of the VIS extensions, but the
-    // codegen doesn't currently use it. Revisit this when vector codegen is
-    // ready.
-    return 0;
-  }
-
-  llvm_unreachable("Unsupported register class");
-}
-
-TypeSize
-SparcTTIImpl::getRegisterBitWidth(TargetTransformInfo::RegisterKind K) const {
-  switch (K) {
-  case TargetTransformInfo::RGK_Scalar:
-    // TODO When targeting V8+ ABI, G and O registers are 64-bit.
-    return TypeSize::getFixed(ST->is64Bit() ? 64 : 32);
-  case TargetTransformInfo::RGK_FixedWidthVector:
-    // TODO We have vector capabilities as part of the VIS extensions, but the
-    // codegen doesn't currently use it. Revisit this when vector codegen is
-    // ready.
-    return TypeSize::getFixed(0);
-  case TargetTransformInfo::RGK_ScalableVector:
-    return TypeSize::getScalable(0);
-  }
-
-  llvm_unreachable("Unsupported register kind");
-}
diff --git a/llvm/lib/Target/Sparc/SparcTargetTransformInfo.h b/llvm/lib/Target/Sparc/SparcTargetTransformInfo.h
index 0d1048c93f7ad..3bf9a197ae1d5 100644
--- a/llvm/lib/Target/Sparc/SparcTargetTransformInfo.h
+++ b/llvm/lib/Target/Sparc/SparcTargetTransformInfo.h
@@ -40,31 +40,9 @@ class SparcTTIImpl final : public BasicTTIImplBase<SparcTTIImpl> {
 
   /// \name Scalar TTI Implementations
   /// @{
-  InstructionCost getIntImmCost(const APInt &Imm, Type *Ty,
-                                TTI::TargetCostKind CostKind) const override;
-
-  InstructionCost getIntImmCostInst(unsigned Opcode, unsigned Idx,
-                                    const APInt &Imm, Type *Ty,
-                                    TTI::TargetCostKind CostKind,
-                                    Instruction *Inst = nullptr) const override;
-  InstructionCost
-  getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx, const APInt &Imm,
-                      Type *Ty, TTI::TargetCostKind CostKind) const override {
-    return getIntImmCost(Imm, Ty, CostKind);
-  };
 
   TTI::PopcntSupportKind getPopcntSupport(unsigned TyWidth) const override;
   /// @}
-
-  /// \name Vector TTI Implementations
-  /// @{
-  enum SparcRegisterClass { GPRRC, FPRRC, FP128RRC, VRRC };
-  unsigned getNumberOfRegisters(unsigned ClassID) const override;
-  unsigned getRegisterClassForType(bool Vector,
-                                   Type *Ty = nullptr) const override;
-  TypeSize
-  getRegisterBitWidth(TargetTransformInfo::RegisterKind K) const override;
-  /// @}
 };
 
 } // end namespace llvm

>From 8e7512554c310d5f2bc54933749205556d482d17 Mon Sep 17 00:00:00 2001
From: Koakuma <koachan at protonmail.com>
Date: Sat, 31 Jan 2026 17:49:43 +0700
Subject: [PATCH 7/8] Update tests

---
 .../test/Transforms/LoopIdiom/Sparc/popcnt.ll | 43 +++++++++++++------
 1 file changed, 29 insertions(+), 14 deletions(-)

diff --git a/llvm/test/Transforms/LoopIdiom/Sparc/popcnt.ll b/llvm/test/Transforms/LoopIdiom/Sparc/popcnt.ll
index 3d4a86db1c3fc..916a81645b3fa 100644
--- a/llvm/test/Transforms/LoopIdiom/Sparc/popcnt.ll
+++ b/llvm/test/Transforms/LoopIdiom/Sparc/popcnt.ll
@@ -1,5 +1,5 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -passes=loop-idiom -mtriple=sparc -mattr=+popc -S < %s | FileCheck %s --check-prefixes=SPARC-CPOP
+; RUN: opt -passes=loop-idiom -mtriple=sparc -mattr=+v9,+popc -S < %s | FileCheck %s --check-prefixes=SPARC-CPOP
 ; RUN: opt -passes=loop-idiom -mtriple=sparcv9 -mattr=+popc -S < %s | FileCheck %s --check-prefixes=SPARC64-CPOP
 ; RUN: opt -passes=loop-idiom -mtriple=sparc -S < %s | FileCheck %s --check-prefixes=SPARC-NOCPOP
 ; RUN: opt -passes=loop-idiom -mtriple=sparcv9 -S < %s | FileCheck %s --check-prefixes=SPARC64-NOCPOP
@@ -20,20 +20,24 @@
 define i32 @popcount_i64(i64 %a) nounwind uwtable readnone ssp {
 ; SPARC-CPOP-LABEL: @popcount_i64(
 ; SPARC-CPOP-NEXT:  entry:
-; SPARC-CPOP-NEXT:    [[TOBOOL3:%.*]] = icmp eq i64 [[A:%.*]], 0
+; SPARC-CPOP-NEXT:    [[TMP0:%.*]] = call i64 @llvm.ctpop.i64(i64 [[A:%.*]])
+; SPARC-CPOP-NEXT:    [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32
+; SPARC-CPOP-NEXT:    [[TOBOOL3:%.*]] = icmp eq i32 [[TMP1]], 0
 ; SPARC-CPOP-NEXT:    br i1 [[TOBOOL3]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
 ; SPARC-CPOP:       while.body.preheader:
 ; SPARC-CPOP-NEXT:    br label [[WHILE_BODY:%.*]]
 ; SPARC-CPOP:       while.body:
+; SPARC-CPOP-NEXT:    [[TCPHI:%.*]] = phi i32 [ [[TMP1]], [[WHILE_BODY_PREHEADER]] ], [ [[TCDEC:%.*]], [[WHILE_BODY]] ]
 ; SPARC-CPOP-NEXT:    [[C_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
 ; SPARC-CPOP-NEXT:    [[A_ADDR_04:%.*]] = phi i64 [ [[AND:%.*]], [[WHILE_BODY]] ], [ [[A]], [[WHILE_BODY_PREHEADER]] ]
 ; SPARC-CPOP-NEXT:    [[INC]] = add nsw i32 [[C_05]], 1
 ; SPARC-CPOP-NEXT:    [[SUB:%.*]] = add i64 [[A_ADDR_04]], -1
 ; SPARC-CPOP-NEXT:    [[AND]] = and i64 [[SUB]], [[A_ADDR_04]]
-; SPARC-CPOP-NEXT:    [[TOBOOL:%.*]] = icmp eq i64 [[AND]], 0
+; SPARC-CPOP-NEXT:    [[TCDEC]] = sub nsw i32 [[TCPHI]], 1
+; SPARC-CPOP-NEXT:    [[TOBOOL:%.*]] = icmp sle i32 [[TCDEC]], 0
 ; SPARC-CPOP-NEXT:    br i1 [[TOBOOL]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY]]
 ; SPARC-CPOP:       while.end.loopexit:
-; SPARC-CPOP-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ]
+; SPARC-CPOP-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[TMP1]], [[WHILE_BODY]] ]
 ; SPARC-CPOP-NEXT:    br label [[WHILE_END]]
 ; SPARC-CPOP:       while.end:
 ; SPARC-CPOP-NEXT:    [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
@@ -127,20 +131,23 @@ while.end:                                        ; preds = %while.body, %entry
 define i32 @popcount_i32(i32 %a) nounwind uwtable readnone ssp {
 ; SPARC-CPOP-LABEL: @popcount_i32(
 ; SPARC-CPOP-NEXT:  entry:
-; SPARC-CPOP-NEXT:    [[TOBOOL3:%.*]] = icmp eq i32 [[A:%.*]], 0
+; SPARC-CPOP-NEXT:    [[A:%.*]] = call i32 @llvm.ctpop.i32(i32 [[A1:%.*]])
+; SPARC-CPOP-NEXT:    [[TOBOOL3:%.*]] = icmp eq i32 [[A]], 0
 ; SPARC-CPOP-NEXT:    br i1 [[TOBOOL3]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
 ; SPARC-CPOP:       while.body.preheader:
 ; SPARC-CPOP-NEXT:    br label [[WHILE_BODY:%.*]]
 ; SPARC-CPOP:       while.body:
+; SPARC-CPOP-NEXT:    [[TCPHI:%.*]] = phi i32 [ [[A]], [[WHILE_BODY_PREHEADER]] ], [ [[TCDEC:%.*]], [[WHILE_BODY]] ]
 ; SPARC-CPOP-NEXT:    [[C_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
-; SPARC-CPOP-NEXT:    [[A_ADDR_04:%.*]] = phi i32 [ [[AND:%.*]], [[WHILE_BODY]] ], [ [[A]], [[WHILE_BODY_PREHEADER]] ]
+; SPARC-CPOP-NEXT:    [[A_ADDR_04:%.*]] = phi i32 [ [[AND:%.*]], [[WHILE_BODY]] ], [ [[A1]], [[WHILE_BODY_PREHEADER]] ]
 ; SPARC-CPOP-NEXT:    [[INC]] = add nsw i32 [[C_05]], 1
 ; SPARC-CPOP-NEXT:    [[SUB:%.*]] = add i32 [[A_ADDR_04]], -1
 ; SPARC-CPOP-NEXT:    [[AND]] = and i32 [[SUB]], [[A_ADDR_04]]
-; SPARC-CPOP-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[AND]], 0
+; SPARC-CPOP-NEXT:    [[TCDEC]] = sub nsw i32 [[TCPHI]], 1
+; SPARC-CPOP-NEXT:    [[TOBOOL:%.*]] = icmp sle i32 [[TCDEC]], 0
 ; SPARC-CPOP-NEXT:    br i1 [[TOBOOL]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY]]
 ; SPARC-CPOP:       while.end.loopexit:
-; SPARC-CPOP-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ]
+; SPARC-CPOP-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[A]], [[WHILE_BODY]] ]
 ; SPARC-CPOP-NEXT:    br label [[WHILE_END]]
 ; SPARC-CPOP:       while.end:
 ; SPARC-CPOP-NEXT:    [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
@@ -233,20 +240,24 @@ while.end:                                        ; preds = %while.body, %entry
 define i32 @popcount_i128(i128 %a) nounwind uwtable readnone ssp {
 ; SPARC-CPOP-LABEL: @popcount_i128(
 ; SPARC-CPOP-NEXT:  entry:
-; SPARC-CPOP-NEXT:    [[TOBOOL3:%.*]] = icmp eq i128 [[A:%.*]], 0
+; SPARC-CPOP-NEXT:    [[TMP0:%.*]] = call i128 @llvm.ctpop.i128(i128 [[A:%.*]])
+; SPARC-CPOP-NEXT:    [[TMP1:%.*]] = trunc i128 [[TMP0]] to i32
+; SPARC-CPOP-NEXT:    [[TOBOOL3:%.*]] = icmp eq i32 [[TMP1]], 0
 ; SPARC-CPOP-NEXT:    br i1 [[TOBOOL3]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
 ; SPARC-CPOP:       while.body.preheader:
 ; SPARC-CPOP-NEXT:    br label [[WHILE_BODY:%.*]]
 ; SPARC-CPOP:       while.body:
+; SPARC-CPOP-NEXT:    [[TCPHI:%.*]] = phi i32 [ [[TMP1]], [[WHILE_BODY_PREHEADER]] ], [ [[TCDEC:%.*]], [[WHILE_BODY]] ]
 ; SPARC-CPOP-NEXT:    [[C_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
 ; SPARC-CPOP-NEXT:    [[A_ADDR_04:%.*]] = phi i128 [ [[AND:%.*]], [[WHILE_BODY]] ], [ [[A]], [[WHILE_BODY_PREHEADER]] ]
 ; SPARC-CPOP-NEXT:    [[INC]] = add nsw i32 [[C_05]], 1
 ; SPARC-CPOP-NEXT:    [[SUB:%.*]] = add i128 [[A_ADDR_04]], -1
 ; SPARC-CPOP-NEXT:    [[AND]] = and i128 [[SUB]], [[A_ADDR_04]]
-; SPARC-CPOP-NEXT:    [[TOBOOL:%.*]] = icmp eq i128 [[AND]], 0
+; SPARC-CPOP-NEXT:    [[TCDEC]] = sub nsw i32 [[TCPHI]], 1
+; SPARC-CPOP-NEXT:    [[TOBOOL:%.*]] = icmp sle i32 [[TCDEC]], 0
 ; SPARC-CPOP-NEXT:    br i1 [[TOBOOL]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY]]
 ; SPARC-CPOP:       while.end.loopexit:
-; SPARC-CPOP-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ]
+; SPARC-CPOP-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[TMP1]], [[WHILE_BODY]] ]
 ; SPARC-CPOP-NEXT:    br label [[WHILE_END]]
 ; SPARC-CPOP:       while.end:
 ; SPARC-CPOP-NEXT:    [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
@@ -352,11 +363,14 @@ while.end:                                        ; preds = %while.body, %entry
 define i32 @popcount2(i64 %a, i32 %mydata1, i32 %mydata2) nounwind uwtable readnone ssp {
 ; SPARC-CPOP-LABEL: @popcount2(
 ; SPARC-CPOP-NEXT:  entry:
-; SPARC-CPOP-NEXT:    [[TOBOOL9:%.*]] = icmp eq i64 [[A:%.*]], 0
+; SPARC-CPOP-NEXT:    [[TMP0:%.*]] = call i64 @llvm.ctpop.i64(i64 [[A:%.*]])
+; SPARC-CPOP-NEXT:    [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32
+; SPARC-CPOP-NEXT:    [[TOBOOL9:%.*]] = icmp eq i32 [[TMP1]], 0
 ; SPARC-CPOP-NEXT:    br i1 [[TOBOOL9]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
 ; SPARC-CPOP:       while.body.preheader:
 ; SPARC-CPOP-NEXT:    br label [[WHILE_BODY:%.*]]
 ; SPARC-CPOP:       while.body:
+; SPARC-CPOP-NEXT:    [[TCPHI:%.*]] = phi i32 [ [[TMP1]], [[WHILE_BODY_PREHEADER]] ], [ [[TCDEC:%.*]], [[WHILE_BODY]] ]
 ; SPARC-CPOP-NEXT:    [[C_013:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
 ; SPARC-CPOP-NEXT:    [[MYDATA2_ADDR_012:%.*]] = phi i32 [ [[MUL1:%.*]], [[WHILE_BODY]] ], [ [[MYDATA2:%.*]], [[WHILE_BODY_PREHEADER]] ]
 ; SPARC-CPOP-NEXT:    [[MYDATA1_ADDR_011:%.*]] = phi i32 [ [[MUL:%.*]], [[WHILE_BODY]] ], [ [[MYDATA1:%.*]], [[WHILE_BODY_PREHEADER]] ]
@@ -367,10 +381,11 @@ define i32 @popcount2(i64 %a, i32 %mydata1, i32 %mydata2) nounwind uwtable readn
 ; SPARC-CPOP-NEXT:    [[MUL]] = mul nsw i32 [[INC]], [[MYDATA1_ADDR_011]]
 ; SPARC-CPOP-NEXT:    [[CONV:%.*]] = trunc i64 [[AND]] to i32
 ; SPARC-CPOP-NEXT:    [[MUL1]] = mul nsw i32 [[CONV]], [[MYDATA2_ADDR_012]]
-; SPARC-CPOP-NEXT:    [[TOBOOL:%.*]] = icmp eq i64 [[AND]], 0
+; SPARC-CPOP-NEXT:    [[TCDEC]] = sub nsw i32 [[TCPHI]], 1
+; SPARC-CPOP-NEXT:    [[TOBOOL:%.*]] = icmp sle i32 [[TCDEC]], 0
 ; SPARC-CPOP-NEXT:    br i1 [[TOBOOL]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY]]
 ; SPARC-CPOP:       while.end.loopexit:
-; SPARC-CPOP-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ]
+; SPARC-CPOP-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[TMP1]], [[WHILE_BODY]] ]
 ; SPARC-CPOP-NEXT:    [[MUL_LCSSA:%.*]] = phi i32 [ [[MUL]], [[WHILE_BODY]] ]
 ; SPARC-CPOP-NEXT:    [[MUL1_LCSSA:%.*]] = phi i32 [ [[MUL1]], [[WHILE_BODY]] ]
 ; SPARC-CPOP-NEXT:    br label [[WHILE_END]]

>From 49e11b725ff428bdef6ff7289715c50f90eafb51 Mon Sep 17 00:00:00 2001
From: Koakuma <koachan at protonmail.com>
Date: Mon, 9 Feb 2026 22:30:45 +0700
Subject: [PATCH 8/8] Use common test prefix to reduce test size

---
 .../test/Transforms/LoopIdiom/Sparc/popcnt.ll | 221 +-----------------
 1 file changed, 10 insertions(+), 211 deletions(-)

diff --git a/llvm/test/Transforms/LoopIdiom/Sparc/popcnt.ll b/llvm/test/Transforms/LoopIdiom/Sparc/popcnt.ll
index 916a81645b3fa..cfbcffe8fe66e 100644
--- a/llvm/test/Transforms/LoopIdiom/Sparc/popcnt.ll
+++ b/llvm/test/Transforms/LoopIdiom/Sparc/popcnt.ll
@@ -1,8 +1,8 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -passes=loop-idiom -mtriple=sparc -mattr=+v9,+popc -S < %s | FileCheck %s --check-prefixes=SPARC-CPOP
-; RUN: opt -passes=loop-idiom -mtriple=sparcv9 -mattr=+popc -S < %s | FileCheck %s --check-prefixes=SPARC64-CPOP
-; RUN: opt -passes=loop-idiom -mtriple=sparc -S < %s | FileCheck %s --check-prefixes=SPARC-NOCPOP
-; RUN: opt -passes=loop-idiom -mtriple=sparcv9 -S < %s | FileCheck %s --check-prefixes=SPARC64-NOCPOP
+ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -passes=loop-idiom -mtriple=sparc -mattr=+v9,+popc -S < %s | FileCheck %s --check-prefixes=SPARC-CPOP,SPARC32-CPOP
+; RUN: opt -passes=loop-idiom -mtriple=sparcv9 -mattr=+popc -S < %s | FileCheck %s --check-prefixes=SPARC-CPOP,SPARC64-CPOP
+; RUN: opt -passes=loop-idiom -mtriple=sparc -S < %s | FileCheck %s --check-prefixes=SPARC-NOCPOP,SPARC32-NOCPOP
+; RUN: opt -passes=loop-idiom -mtriple=sparcv9 -S < %s | FileCheck %s --check-prefixes=SPARC-NOCPOP,SPARC64-NOCPOP
 
 ; Mostly copied from AMDGPU version.
 
@@ -43,31 +43,6 @@ define i32 @popcount_i64(i64 %a) nounwind uwtable readnone ssp {
 ; SPARC-CPOP-NEXT:    [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
 ; SPARC-CPOP-NEXT:    ret i32 [[C_0_LCSSA]]
 ;
-; SPARC64-CPOP-LABEL: @popcount_i64(
-; SPARC64-CPOP-NEXT:  entry:
-; SPARC64-CPOP-NEXT:    [[TMP0:%.*]] = call i64 @llvm.ctpop.i64(i64 [[A:%.*]])
-; SPARC64-CPOP-NEXT:    [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32
-; SPARC64-CPOP-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
-; SPARC64-CPOP-NEXT:    br i1 [[TMP2]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
-; SPARC64-CPOP:       while.body.preheader:
-; SPARC64-CPOP-NEXT:    br label [[WHILE_BODY:%.*]]
-; SPARC64-CPOP:       while.body:
-; SPARC64-CPOP-NEXT:    [[TCPHI:%.*]] = phi i32 [ [[TMP1]], [[WHILE_BODY_PREHEADER]] ], [ [[TCDEC:%.*]], [[WHILE_BODY]] ]
-; SPARC64-CPOP-NEXT:    [[C_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
-; SPARC64-CPOP-NEXT:    [[A_ADDR_04:%.*]] = phi i64 [ [[AND:%.*]], [[WHILE_BODY]] ], [ [[A]], [[WHILE_BODY_PREHEADER]] ]
-; SPARC64-CPOP-NEXT:    [[INC]] = add nsw i32 [[C_05]], 1
-; SPARC64-CPOP-NEXT:    [[SUB:%.*]] = add i64 [[A_ADDR_04]], -1
-; SPARC64-CPOP-NEXT:    [[AND]] = and i64 [[SUB]], [[A_ADDR_04]]
-; SPARC64-CPOP-NEXT:    [[TCDEC]] = sub nsw i32 [[TCPHI]], 1
-; SPARC64-CPOP-NEXT:    [[TOBOOL:%.*]] = icmp sle i32 [[TCDEC]], 0
-; SPARC64-CPOP-NEXT:    br i1 [[TOBOOL]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY]]
-; SPARC64-CPOP:       while.end.loopexit:
-; SPARC64-CPOP-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[TMP1]], [[WHILE_BODY]] ]
-; SPARC64-CPOP-NEXT:    br label [[WHILE_END]]
-; SPARC64-CPOP:       while.end:
-; SPARC64-CPOP-NEXT:    [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
-; SPARC64-CPOP-NEXT:    ret i32 [[C_0_LCSSA]]
-;
 ; SPARC-NOCPOP-LABEL: @popcount_i64(
 ; SPARC-NOCPOP-NEXT:  entry:
 ; SPARC-NOCPOP-NEXT:    [[TOBOOL3:%.*]] = icmp eq i64 [[A:%.*]], 0
@@ -89,27 +64,6 @@ define i32 @popcount_i64(i64 %a) nounwind uwtable readnone ssp {
 ; SPARC-NOCPOP-NEXT:    [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
 ; SPARC-NOCPOP-NEXT:    ret i32 [[C_0_LCSSA]]
 ;
-; SPARC64-NOCPOP-LABEL: @popcount_i64(
-; SPARC64-NOCPOP-NEXT:  entry:
-; SPARC64-NOCPOP-NEXT:    [[TOBOOL3:%.*]] = icmp eq i64 [[A:%.*]], 0
-; SPARC64-NOCPOP-NEXT:    br i1 [[TOBOOL3]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
-; SPARC64-NOCPOP:       while.body.preheader:
-; SPARC64-NOCPOP-NEXT:    br label [[WHILE_BODY:%.*]]
-; SPARC64-NOCPOP:       while.body:
-; SPARC64-NOCPOP-NEXT:    [[C_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
-; SPARC64-NOCPOP-NEXT:    [[A_ADDR_04:%.*]] = phi i64 [ [[AND:%.*]], [[WHILE_BODY]] ], [ [[A]], [[WHILE_BODY_PREHEADER]] ]
-; SPARC64-NOCPOP-NEXT:    [[INC]] = add nsw i32 [[C_05]], 1
-; SPARC64-NOCPOP-NEXT:    [[SUB:%.*]] = add i64 [[A_ADDR_04]], -1
-; SPARC64-NOCPOP-NEXT:    [[AND]] = and i64 [[SUB]], [[A_ADDR_04]]
-; SPARC64-NOCPOP-NEXT:    [[TOBOOL:%.*]] = icmp eq i64 [[AND]], 0
-; SPARC64-NOCPOP-NEXT:    br i1 [[TOBOOL]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY]]
-; SPARC64-NOCPOP:       while.end.loopexit:
-; SPARC64-NOCPOP-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ]
-; SPARC64-NOCPOP-NEXT:    br label [[WHILE_END]]
-; SPARC64-NOCPOP:       while.end:
-; SPARC64-NOCPOP-NEXT:    [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
-; SPARC64-NOCPOP-NEXT:    ret i32 [[C_0_LCSSA]]
-;
 entry:
   %tobool3 = icmp eq i64 %a, 0
   br i1 %tobool3, label %while.end, label %while.body
@@ -153,30 +107,6 @@ define i32 @popcount_i32(i32 %a) nounwind uwtable readnone ssp {
 ; SPARC-CPOP-NEXT:    [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
 ; SPARC-CPOP-NEXT:    ret i32 [[C_0_LCSSA]]
 ;
-; SPARC64-CPOP-LABEL: @popcount_i32(
-; SPARC64-CPOP-NEXT:  entry:
-; SPARC64-CPOP-NEXT:    [[TMP0:%.*]] = call i32 @llvm.ctpop.i32(i32 [[A:%.*]])
-; SPARC64-CPOP-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 0
-; SPARC64-CPOP-NEXT:    br i1 [[TMP1]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
-; SPARC64-CPOP:       while.body.preheader:
-; SPARC64-CPOP-NEXT:    br label [[WHILE_BODY:%.*]]
-; SPARC64-CPOP:       while.body:
-; SPARC64-CPOP-NEXT:    [[TCPHI:%.*]] = phi i32 [ [[TMP0]], [[WHILE_BODY_PREHEADER]] ], [ [[TCDEC:%.*]], [[WHILE_BODY]] ]
-; SPARC64-CPOP-NEXT:    [[C_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
-; SPARC64-CPOP-NEXT:    [[A_ADDR_04:%.*]] = phi i32 [ [[AND:%.*]], [[WHILE_BODY]] ], [ [[A]], [[WHILE_BODY_PREHEADER]] ]
-; SPARC64-CPOP-NEXT:    [[INC]] = add nsw i32 [[C_05]], 1
-; SPARC64-CPOP-NEXT:    [[SUB:%.*]] = add i32 [[A_ADDR_04]], -1
-; SPARC64-CPOP-NEXT:    [[AND]] = and i32 [[SUB]], [[A_ADDR_04]]
-; SPARC64-CPOP-NEXT:    [[TCDEC]] = sub nsw i32 [[TCPHI]], 1
-; SPARC64-CPOP-NEXT:    [[TOBOOL:%.*]] = icmp sle i32 [[TCDEC]], 0
-; SPARC64-CPOP-NEXT:    br i1 [[TOBOOL]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY]]
-; SPARC64-CPOP:       while.end.loopexit:
-; SPARC64-CPOP-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[TMP0]], [[WHILE_BODY]] ]
-; SPARC64-CPOP-NEXT:    br label [[WHILE_END]]
-; SPARC64-CPOP:       while.end:
-; SPARC64-CPOP-NEXT:    [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
-; SPARC64-CPOP-NEXT:    ret i32 [[C_0_LCSSA]]
-;
 ; SPARC-NOCPOP-LABEL: @popcount_i32(
 ; SPARC-NOCPOP-NEXT:  entry:
 ; SPARC-NOCPOP-NEXT:    [[TOBOOL3:%.*]] = icmp eq i32 [[A:%.*]], 0
@@ -198,27 +128,6 @@ define i32 @popcount_i32(i32 %a) nounwind uwtable readnone ssp {
 ; SPARC-NOCPOP-NEXT:    [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
 ; SPARC-NOCPOP-NEXT:    ret i32 [[C_0_LCSSA]]
 ;
-; SPARC64-NOCPOP-LABEL: @popcount_i32(
-; SPARC64-NOCPOP-NEXT:  entry:
-; SPARC64-NOCPOP-NEXT:    [[TOBOOL3:%.*]] = icmp eq i32 [[A:%.*]], 0
-; SPARC64-NOCPOP-NEXT:    br i1 [[TOBOOL3]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
-; SPARC64-NOCPOP:       while.body.preheader:
-; SPARC64-NOCPOP-NEXT:    br label [[WHILE_BODY:%.*]]
-; SPARC64-NOCPOP:       while.body:
-; SPARC64-NOCPOP-NEXT:    [[C_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
-; SPARC64-NOCPOP-NEXT:    [[A_ADDR_04:%.*]] = phi i32 [ [[AND:%.*]], [[WHILE_BODY]] ], [ [[A]], [[WHILE_BODY_PREHEADER]] ]
-; SPARC64-NOCPOP-NEXT:    [[INC]] = add nsw i32 [[C_05]], 1
-; SPARC64-NOCPOP-NEXT:    [[SUB:%.*]] = add i32 [[A_ADDR_04]], -1
-; SPARC64-NOCPOP-NEXT:    [[AND]] = and i32 [[SUB]], [[A_ADDR_04]]
-; SPARC64-NOCPOP-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[AND]], 0
-; SPARC64-NOCPOP-NEXT:    br i1 [[TOBOOL]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY]]
-; SPARC64-NOCPOP:       while.end.loopexit:
-; SPARC64-NOCPOP-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ]
-; SPARC64-NOCPOP-NEXT:    br label [[WHILE_END]]
-; SPARC64-NOCPOP:       while.end:
-; SPARC64-NOCPOP-NEXT:    [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
-; SPARC64-NOCPOP-NEXT:    ret i32 [[C_0_LCSSA]]
-;
 entry:
   %tobool3 = icmp eq i32 %a, 0
   br i1 %tobool3, label %while.end, label %while.body
@@ -263,31 +172,6 @@ define i32 @popcount_i128(i128 %a) nounwind uwtable readnone ssp {
 ; SPARC-CPOP-NEXT:    [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
 ; SPARC-CPOP-NEXT:    ret i32 [[C_0_LCSSA]]
 ;
-; SPARC64-CPOP-LABEL: @popcount_i128(
-; SPARC64-CPOP-NEXT:  entry:
-; SPARC64-CPOP-NEXT:    [[TMP0:%.*]] = call i128 @llvm.ctpop.i128(i128 [[A:%.*]])
-; SPARC64-CPOP-NEXT:    [[TMP1:%.*]] = trunc i128 [[TMP0]] to i32
-; SPARC64-CPOP-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
-; SPARC64-CPOP-NEXT:    br i1 [[TMP2]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
-; SPARC64-CPOP:       while.body.preheader:
-; SPARC64-CPOP-NEXT:    br label [[WHILE_BODY:%.*]]
-; SPARC64-CPOP:       while.body:
-; SPARC64-CPOP-NEXT:    [[TCPHI:%.*]] = phi i32 [ [[TMP1]], [[WHILE_BODY_PREHEADER]] ], [ [[TCDEC:%.*]], [[WHILE_BODY]] ]
-; SPARC64-CPOP-NEXT:    [[C_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
-; SPARC64-CPOP-NEXT:    [[A_ADDR_04:%.*]] = phi i128 [ [[AND:%.*]], [[WHILE_BODY]] ], [ [[A]], [[WHILE_BODY_PREHEADER]] ]
-; SPARC64-CPOP-NEXT:    [[INC]] = add nsw i32 [[C_05]], 1
-; SPARC64-CPOP-NEXT:    [[SUB:%.*]] = add i128 [[A_ADDR_04]], -1
-; SPARC64-CPOP-NEXT:    [[AND]] = and i128 [[SUB]], [[A_ADDR_04]]
-; SPARC64-CPOP-NEXT:    [[TCDEC]] = sub nsw i32 [[TCPHI]], 1
-; SPARC64-CPOP-NEXT:    [[TOBOOL:%.*]] = icmp sle i32 [[TCDEC]], 0
-; SPARC64-CPOP-NEXT:    br i1 [[TOBOOL]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY]]
-; SPARC64-CPOP:       while.end.loopexit:
-; SPARC64-CPOP-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[TMP1]], [[WHILE_BODY]] ]
-; SPARC64-CPOP-NEXT:    br label [[WHILE_END]]
-; SPARC64-CPOP:       while.end:
-; SPARC64-CPOP-NEXT:    [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
-; SPARC64-CPOP-NEXT:    ret i32 [[C_0_LCSSA]]
-;
 ; SPARC-NOCPOP-LABEL: @popcount_i128(
 ; SPARC-NOCPOP-NEXT:  entry:
 ; SPARC-NOCPOP-NEXT:    [[TOBOOL3:%.*]] = icmp eq i128 [[A:%.*]], 0
@@ -309,27 +193,6 @@ define i32 @popcount_i128(i128 %a) nounwind uwtable readnone ssp {
 ; SPARC-NOCPOP-NEXT:    [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
 ; SPARC-NOCPOP-NEXT:    ret i32 [[C_0_LCSSA]]
 ;
-; SPARC64-NOCPOP-LABEL: @popcount_i128(
-; SPARC64-NOCPOP-NEXT:  entry:
-; SPARC64-NOCPOP-NEXT:    [[TOBOOL3:%.*]] = icmp eq i128 [[A:%.*]], 0
-; SPARC64-NOCPOP-NEXT:    br i1 [[TOBOOL3]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
-; SPARC64-NOCPOP:       while.body.preheader:
-; SPARC64-NOCPOP-NEXT:    br label [[WHILE_BODY:%.*]]
-; SPARC64-NOCPOP:       while.body:
-; SPARC64-NOCPOP-NEXT:    [[C_05:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
-; SPARC64-NOCPOP-NEXT:    [[A_ADDR_04:%.*]] = phi i128 [ [[AND:%.*]], [[WHILE_BODY]] ], [ [[A]], [[WHILE_BODY_PREHEADER]] ]
-; SPARC64-NOCPOP-NEXT:    [[INC]] = add nsw i32 [[C_05]], 1
-; SPARC64-NOCPOP-NEXT:    [[SUB:%.*]] = add i128 [[A_ADDR_04]], -1
-; SPARC64-NOCPOP-NEXT:    [[AND]] = and i128 [[SUB]], [[A_ADDR_04]]
-; SPARC64-NOCPOP-NEXT:    [[TOBOOL:%.*]] = icmp eq i128 [[AND]], 0
-; SPARC64-NOCPOP-NEXT:    br i1 [[TOBOOL]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY]]
-; SPARC64-NOCPOP:       while.end.loopexit:
-; SPARC64-NOCPOP-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ]
-; SPARC64-NOCPOP-NEXT:    br label [[WHILE_END]]
-; SPARC64-NOCPOP:       while.end:
-; SPARC64-NOCPOP-NEXT:    [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
-; SPARC64-NOCPOP-NEXT:    ret i32 [[C_0_LCSSA]]
-;
 entry:
   %tobool3 = icmp eq i128 %a, 0
   br i1 %tobool3, label %while.end, label %while.body
@@ -397,42 +260,6 @@ define i32 @popcount2(i64 %a, i32 %mydata1, i32 %mydata2) nounwind uwtable readn
 ; SPARC-CPOP-NEXT:    [[ADD2:%.*]] = add i32 [[ADD]], [[C_0_LCSSA]]
 ; SPARC-CPOP-NEXT:    ret i32 [[ADD2]]
 ;
-; SPARC64-CPOP-LABEL: @popcount2(
-; SPARC64-CPOP-NEXT:  entry:
-; SPARC64-CPOP-NEXT:    [[TMP0:%.*]] = call i64 @llvm.ctpop.i64(i64 [[A:%.*]])
-; SPARC64-CPOP-NEXT:    [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32
-; SPARC64-CPOP-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
-; SPARC64-CPOP-NEXT:    br i1 [[TMP2]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
-; SPARC64-CPOP:       while.body.preheader:
-; SPARC64-CPOP-NEXT:    br label [[WHILE_BODY:%.*]]
-; SPARC64-CPOP:       while.body:
-; SPARC64-CPOP-NEXT:    [[TCPHI:%.*]] = phi i32 [ [[TMP1]], [[WHILE_BODY_PREHEADER]] ], [ [[TCDEC:%.*]], [[WHILE_BODY]] ]
-; SPARC64-CPOP-NEXT:    [[C_013:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
-; SPARC64-CPOP-NEXT:    [[MYDATA2_ADDR_012:%.*]] = phi i32 [ [[MUL1:%.*]], [[WHILE_BODY]] ], [ [[MYDATA2:%.*]], [[WHILE_BODY_PREHEADER]] ]
-; SPARC64-CPOP-NEXT:    [[MYDATA1_ADDR_011:%.*]] = phi i32 [ [[MUL:%.*]], [[WHILE_BODY]] ], [ [[MYDATA1:%.*]], [[WHILE_BODY_PREHEADER]] ]
-; SPARC64-CPOP-NEXT:    [[A_ADDR_010:%.*]] = phi i64 [ [[AND:%.*]], [[WHILE_BODY]] ], [ [[A]], [[WHILE_BODY_PREHEADER]] ]
-; SPARC64-CPOP-NEXT:    [[INC]] = add nsw i32 [[C_013]], 1
-; SPARC64-CPOP-NEXT:    [[SUB:%.*]] = add i64 [[A_ADDR_010]], -1
-; SPARC64-CPOP-NEXT:    [[AND]] = and i64 [[SUB]], [[A_ADDR_010]]
-; SPARC64-CPOP-NEXT:    [[MUL]] = mul nsw i32 [[INC]], [[MYDATA1_ADDR_011]]
-; SPARC64-CPOP-NEXT:    [[CONV:%.*]] = trunc i64 [[AND]] to i32
-; SPARC64-CPOP-NEXT:    [[MUL1]] = mul nsw i32 [[CONV]], [[MYDATA2_ADDR_012]]
-; SPARC64-CPOP-NEXT:    [[TCDEC]] = sub nsw i32 [[TCPHI]], 1
-; SPARC64-CPOP-NEXT:    [[TOBOOL:%.*]] = icmp sle i32 [[TCDEC]], 0
-; SPARC64-CPOP-NEXT:    br i1 [[TOBOOL]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY]]
-; SPARC64-CPOP:       while.end.loopexit:
-; SPARC64-CPOP-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[TMP1]], [[WHILE_BODY]] ]
-; SPARC64-CPOP-NEXT:    [[MUL_LCSSA:%.*]] = phi i32 [ [[MUL]], [[WHILE_BODY]] ]
-; SPARC64-CPOP-NEXT:    [[MUL1_LCSSA:%.*]] = phi i32 [ [[MUL1]], [[WHILE_BODY]] ]
-; SPARC64-CPOP-NEXT:    br label [[WHILE_END]]
-; SPARC64-CPOP:       while.end:
-; SPARC64-CPOP-NEXT:    [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
-; SPARC64-CPOP-NEXT:    [[MYDATA2_ADDR_0_LCSSA:%.*]] = phi i32 [ [[MYDATA2]], [[ENTRY]] ], [ [[MUL1_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
-; SPARC64-CPOP-NEXT:    [[MYDATA1_ADDR_0_LCSSA:%.*]] = phi i32 [ [[MYDATA1]], [[ENTRY]] ], [ [[MUL_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
-; SPARC64-CPOP-NEXT:    [[ADD:%.*]] = add i32 [[MYDATA2_ADDR_0_LCSSA]], [[MYDATA1_ADDR_0_LCSSA]]
-; SPARC64-CPOP-NEXT:    [[ADD2:%.*]] = add i32 [[ADD]], [[C_0_LCSSA]]
-; SPARC64-CPOP-NEXT:    ret i32 [[ADD2]]
-;
 ; SPARC-NOCPOP-LABEL: @popcount2(
 ; SPARC-NOCPOP-NEXT:  entry:
 ; SPARC-NOCPOP-NEXT:    [[TOBOOL9:%.*]] = icmp eq i64 [[A:%.*]], 0
@@ -465,38 +292,6 @@ define i32 @popcount2(i64 %a, i32 %mydata1, i32 %mydata2) nounwind uwtable readn
 ; SPARC-NOCPOP-NEXT:    [[ADD2:%.*]] = add i32 [[ADD]], [[C_0_LCSSA]]
 ; SPARC-NOCPOP-NEXT:    ret i32 [[ADD2]]
 ;
-; SPARC64-NOCPOP-LABEL: @popcount2(
-; SPARC64-NOCPOP-NEXT:  entry:
-; SPARC64-NOCPOP-NEXT:    [[TOBOOL9:%.*]] = icmp eq i64 [[A:%.*]], 0
-; SPARC64-NOCPOP-NEXT:    br i1 [[TOBOOL9]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]]
-; SPARC64-NOCPOP:       while.body.preheader:
-; SPARC64-NOCPOP-NEXT:    br label [[WHILE_BODY:%.*]]
-; SPARC64-NOCPOP:       while.body:
-; SPARC64-NOCPOP-NEXT:    [[C_013:%.*]] = phi i32 [ [[INC:%.*]], [[WHILE_BODY]] ], [ 0, [[WHILE_BODY_PREHEADER]] ]
-; SPARC64-NOCPOP-NEXT:    [[MYDATA2_ADDR_012:%.*]] = phi i32 [ [[MUL1:%.*]], [[WHILE_BODY]] ], [ [[MYDATA2:%.*]], [[WHILE_BODY_PREHEADER]] ]
-; SPARC64-NOCPOP-NEXT:    [[MYDATA1_ADDR_011:%.*]] = phi i32 [ [[MUL:%.*]], [[WHILE_BODY]] ], [ [[MYDATA1:%.*]], [[WHILE_BODY_PREHEADER]] ]
-; SPARC64-NOCPOP-NEXT:    [[A_ADDR_010:%.*]] = phi i64 [ [[AND:%.*]], [[WHILE_BODY]] ], [ [[A]], [[WHILE_BODY_PREHEADER]] ]
-; SPARC64-NOCPOP-NEXT:    [[INC]] = add nsw i32 [[C_013]], 1
-; SPARC64-NOCPOP-NEXT:    [[SUB:%.*]] = add i64 [[A_ADDR_010]], -1
-; SPARC64-NOCPOP-NEXT:    [[AND]] = and i64 [[SUB]], [[A_ADDR_010]]
-; SPARC64-NOCPOP-NEXT:    [[MUL]] = mul nsw i32 [[INC]], [[MYDATA1_ADDR_011]]
-; SPARC64-NOCPOP-NEXT:    [[CONV:%.*]] = trunc i64 [[AND]] to i32
-; SPARC64-NOCPOP-NEXT:    [[MUL1]] = mul nsw i32 [[CONV]], [[MYDATA2_ADDR_012]]
-; SPARC64-NOCPOP-NEXT:    [[TOBOOL:%.*]] = icmp eq i64 [[AND]], 0
-; SPARC64-NOCPOP-NEXT:    br i1 [[TOBOOL]], label [[WHILE_END_LOOPEXIT:%.*]], label [[WHILE_BODY]]
-; SPARC64-NOCPOP:       while.end.loopexit:
-; SPARC64-NOCPOP-NEXT:    [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[WHILE_BODY]] ]
-; SPARC64-NOCPOP-NEXT:    [[MUL_LCSSA:%.*]] = phi i32 [ [[MUL]], [[WHILE_BODY]] ]
-; SPARC64-NOCPOP-NEXT:    [[MUL1_LCSSA:%.*]] = phi i32 [ [[MUL1]], [[WHILE_BODY]] ]
-; SPARC64-NOCPOP-NEXT:    br label [[WHILE_END]]
-; SPARC64-NOCPOP:       while.end:
-; SPARC64-NOCPOP-NEXT:    [[C_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
-; SPARC64-NOCPOP-NEXT:    [[MYDATA2_ADDR_0_LCSSA:%.*]] = phi i32 [ [[MYDATA2]], [[ENTRY]] ], [ [[MUL1_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
-; SPARC64-NOCPOP-NEXT:    [[MYDATA1_ADDR_0_LCSSA:%.*]] = phi i32 [ [[MYDATA1]], [[ENTRY]] ], [ [[MUL_LCSSA]], [[WHILE_END_LOOPEXIT]] ]
-; SPARC64-NOCPOP-NEXT:    [[ADD:%.*]] = add i32 [[MYDATA2_ADDR_0_LCSSA]], [[MYDATA1_ADDR_0_LCSSA]]
-; SPARC64-NOCPOP-NEXT:    [[ADD2:%.*]] = add i32 [[ADD]], [[C_0_LCSSA]]
-; SPARC64-NOCPOP-NEXT:    ret i32 [[ADD2]]
-;
 entry:
   %tobool9 = icmp eq i64 %a, 0
   br i1 %tobool9, label %while.end, label %while.body
@@ -523,4 +318,8 @@ while.end:                                        ; preds = %while.body, %entry
   %add2 = add i32 %add, %c.0.lcssa
   ret i32 %add2
 }
-
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; SPARC32-CPOP: {{.*}}
+; SPARC32-NOCPOP: {{.*}}
+; SPARC64-CPOP: {{.*}}
+; SPARC64-NOCPOP: {{.*}}



More information about the llvm-commits mailing list