1Pull in r200131 from upstream llvm trunk (by Jakob Stoklund Olesen): 2 3 Only generate the popc instruction for SPARC CPUs that implement it. 4 5 The popc instruction is defined in the SPARCv9 instruction set 6 architecture, but it was emulated on CPUs older than Niagara 2. 7 8Introduced here: http://svnweb.freebsd.org/changeset/base/262261 9 10Index: lib/Target/Sparc/SparcISelLowering.cpp 11=================================================================== 12--- lib/Target/Sparc/SparcISelLowering.cpp 13+++ lib/Target/Sparc/SparcISelLowering.cpp 14@@ -1461,7 +1461,8 @@ SparcTargetLowering::SparcTargetLowering(TargetMac 15 setOperationAction(ISD::BR_CC, MVT::i64, Custom); 16 setOperationAction(ISD::SELECT_CC, MVT::i64, Custom); 17 18- setOperationAction(ISD::CTPOP, MVT::i64, Legal); 19+ if (Subtarget->usePopc()) 20+ setOperationAction(ISD::CTPOP, MVT::i64, Legal); 21 setOperationAction(ISD::CTTZ , MVT::i64, Expand); 22 setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i64, Expand); 23 setOperationAction(ISD::CTLZ , MVT::i64, Expand); 24@@ -1567,7 +1568,7 @@ SparcTargetLowering::SparcTargetLowering(TargetMac 25 26 setStackPointerRegisterToSaveRestore(SP::O6); 27 28- if (Subtarget->isV9()) 29+ if (Subtarget->isV9() && Subtarget->usePopc()) 30 setOperationAction(ISD::CTPOP, MVT::i32, Legal); 31 32 if (Subtarget->isV9() && Subtarget->hasHardQuad()) { 33Index: lib/Target/Sparc/Sparc.td 34=================================================================== 35--- lib/Target/Sparc/Sparc.td 36+++ lib/Target/Sparc/Sparc.td 37@@ -34,6 +34,9 @@ def FeatureHardQuad 38 : SubtargetFeature<"hard-quad-float", "HasHardQuad", "true", 39 "Enable quad-word floating point instructions">; 40 41+def UsePopc : SubtargetFeature<"popc", "UsePopc", "true", 42+ "Use the popc (population count) instruction">; 43+ 44 //===----------------------------------------------------------------------===// 45 // Register File, Calling Conv, Instruction Descriptions 46 //===----------------------------------------------------------------------===// 47@@ -69,9 +72,9 @@ def : Proc<"v9", [FeatureV9]>; 48 def : Proc<"ultrasparc", [FeatureV9, FeatureV8Deprecated]>; 49 def : Proc<"ultrasparc3", [FeatureV9, FeatureV8Deprecated]>; 50 def : Proc<"niagara", [FeatureV9, FeatureV8Deprecated]>; 51-def : Proc<"niagara2", [FeatureV9, FeatureV8Deprecated]>; 52-def : Proc<"niagara3", [FeatureV9, FeatureV8Deprecated]>; 53-def : Proc<"niagara4", [FeatureV9, FeatureV8Deprecated]>; 54+def : Proc<"niagara2", [FeatureV9, FeatureV8Deprecated, UsePopc]>; 55+def : Proc<"niagara3", [FeatureV9, FeatureV8Deprecated, UsePopc]>; 56+def : Proc<"niagara4", [FeatureV9, FeatureV8Deprecated, UsePopc]>; 57 58 def SparcAsmWriter : AsmWriter { 59 string AsmWriterClassName = "InstPrinter"; 60Index: lib/Target/Sparc/SparcSubtarget.h 61=================================================================== 62--- lib/Target/Sparc/SparcSubtarget.h 63+++ lib/Target/Sparc/SparcSubtarget.h 64@@ -30,6 +30,7 @@ class SparcSubtarget : public SparcGenSubtargetInf 65 bool IsVIS; 66 bool Is64Bit; 67 bool HasHardQuad; 68+ bool UsePopc; 69 70 public: 71 SparcSubtarget(const std::string &TT, const std::string &CPU, 72@@ -39,6 +40,7 @@ class SparcSubtarget : public SparcGenSubtargetInf 73 bool isVIS() const { return IsVIS; } 74 bool useDeprecatedV8Instructions() const { return V8DeprecatedInsts; } 75 bool hasHardQuad() const { return HasHardQuad; } 76+ bool usePopc() const { return UsePopc; } 77 78 /// ParseSubtargetFeatures - Parses features string setting specified 79 /// subtarget options. Definition of function is auto generated by tblgen. 80Index: lib/Target/Sparc/SparcSubtarget.cpp 81=================================================================== 82--- lib/Target/Sparc/SparcSubtarget.cpp 83+++ lib/Target/Sparc/SparcSubtarget.cpp 84@@ -31,7 +31,8 @@ SparcSubtarget::SparcSubtarget(const std::string & 85 V8DeprecatedInsts(false), 86 IsVIS(false), 87 Is64Bit(is64Bit), 88- HasHardQuad(false) { 89+ HasHardQuad(false), 90+ UsePopc(false) { 91 92 // Determine default and user specified characteristics 93 std::string CPUName = CPU; 94Index: test/CodeGen/SPARC/ctpop.ll 95=================================================================== 96--- test/CodeGen/SPARC/ctpop.ll 97+++ test/CodeGen/SPARC/ctpop.ll 98@@ -1,13 +1,13 @@ 99 ; RUN: llc < %s -march=sparc -mattr=-v9 | FileCheck %s -check-prefix=V8 100-; RUN: llc < %s -march=sparc -mattr=+v9 | FileCheck %s -check-prefix=V9 101-; RUN: llc < %s -march=sparc -mcpu=v9 | FileCheck %s -check-prefix=V9 102-; RUN: llc < %s -march=sparc -mcpu=ultrasparc | FileCheck %s -check-prefix=V9 103-; RUN: llc < %s -march=sparc -mcpu=ultrasparc3 | FileCheck %s -check-prefix=V9 104-; RUN: llc < %s -march=sparc -mcpu=niagara | FileCheck %s -check-prefix=V9 105+; RUN: llc < %s -march=sparc -mattr=+v9,+popc | FileCheck %s -check-prefix=V9 106+; RUN: llc < %s -march=sparc -mcpu=v9 | FileCheck %s -check-prefix=V8 107+; RUN: llc < %s -march=sparc -mcpu=ultrasparc | FileCheck %s -check-prefix=V8 108+; RUN: llc < %s -march=sparc -mcpu=ultrasparc3 | FileCheck %s -check-prefix=V8 109+; RUN: llc < %s -march=sparc -mcpu=niagara | FileCheck %s -check-prefix=V8 110 ; RUN: llc < %s -march=sparc -mcpu=niagara2 | FileCheck %s -check-prefix=V9 111 ; RUN: llc < %s -march=sparc -mcpu=niagara3 | FileCheck %s -check-prefix=V9 112 ; RUN: llc < %s -march=sparc -mcpu=niagara4 | FileCheck %s -check-prefix=V9 113-; RUN: llc < %s -march=sparcv9 | FileCheck %s -check-prefix=SPARC64 114+; RUN: llc < %s -march=sparcv9 -mattr=+popc | FileCheck %s -check-prefix=SPARC64 115 116 declare i32 @llvm.ctpop.i32(i32) 117 118