[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