[Power9] Builtins for ELF v.2 API conformance - back end portion
This patch corresponds to review:
https://reviews.llvm.org/D24396
This patch adds support for the "vector count trailing zeroes",
"vector compare not equal" and "vector compare not equal or zero instructions"
as well as "scalar count trailing zeroes" instructions. It also changes the
vector negation to use XXLNOR (when VSX is enabled) so as not to increase
register pressure (previously this was done with a splat immediate of all
ones followed by an XXLXOR). This was done because the altivec.h
builtins (patch to follow) use vector negation and the use of an additional
register for the splat immediate is not optimal.
llvm-svn: 282478
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 5bce336..d203404 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -216,11 +216,17 @@
setOperationAction(ISD::FROUND, MVT::f32, Legal);
}
- // PowerPC does not have BSWAP, CTPOP or CTTZ
+ // PowerPC does not have BSWAP
+ // CTPOP or CTTZ were introduced in P8/P9 respectivelly
setOperationAction(ISD::BSWAP, MVT::i32 , Expand);
- setOperationAction(ISD::CTTZ , MVT::i32 , Expand);
setOperationAction(ISD::BSWAP, MVT::i64 , Expand);
- setOperationAction(ISD::CTTZ , MVT::i64 , Expand);
+ if (Subtarget.isISA3_0()) {
+ setOperationAction(ISD::CTTZ , MVT::i32 , Legal);
+ setOperationAction(ISD::CTTZ , MVT::i64 , Legal);
+ } else {
+ setOperationAction(ISD::CTTZ , MVT::i32 , Expand);
+ setOperationAction(ISD::CTTZ , MVT::i64 , Expand);
+ }
if (Subtarget.hasPOPCNTD() == PPCSubtarget::POPCNTD_Fast) {
setOperationAction(ISD::CTPOP, MVT::i32 , Legal);
@@ -433,6 +439,12 @@
setOperationAction(ISD::CTLZ, VT, Expand);
}
+ // Vector instructions introduced in P9
+ if (Subtarget.hasP9Altivec() && (VT.SimpleTy != MVT::v1i128))
+ setOperationAction(ISD::CTTZ, VT, Legal);
+ else
+ setOperationAction(ISD::CTTZ, VT, Expand);
+
// We promote all shuffles to v16i8.
setOperationAction(ISD::VECTOR_SHUFFLE, VT, Promote);
AddPromotedToType (ISD::VECTOR_SHUFFLE, VT, MVT::v16i8);
@@ -489,7 +501,6 @@
setOperationAction(ISD::SCALAR_TO_VECTOR, VT, Expand);
setOperationAction(ISD::FPOW, VT, Expand);
setOperationAction(ISD::BSWAP, VT, Expand);
- setOperationAction(ISD::CTTZ, VT, Expand);
setOperationAction(ISD::VSELECT, VT, Expand);
setOperationAction(ISD::SIGN_EXTEND_INREG, VT, Expand);
setOperationAction(ISD::ROTL, VT, Expand);
@@ -7711,6 +7722,27 @@
return false;
break;
+ case Intrinsic::ppc_altivec_vcmpneb_p:
+ case Intrinsic::ppc_altivec_vcmpneh_p:
+ case Intrinsic::ppc_altivec_vcmpnew_p:
+ case Intrinsic::ppc_altivec_vcmpnezb_p:
+ case Intrinsic::ppc_altivec_vcmpnezh_p:
+ case Intrinsic::ppc_altivec_vcmpnezw_p:
+ if (Subtarget.hasP9Altivec()) {
+ switch(IntrinsicID) {
+ default: llvm_unreachable("Unknown comparison intrinsic.");
+ case Intrinsic::ppc_altivec_vcmpneb_p: CompareOpc = 7; break;
+ case Intrinsic::ppc_altivec_vcmpneh_p: CompareOpc = 71; break;
+ case Intrinsic::ppc_altivec_vcmpnew_p: CompareOpc = 135; break;
+ case Intrinsic::ppc_altivec_vcmpnezb_p: CompareOpc = 263; break;
+ case Intrinsic::ppc_altivec_vcmpnezh_p: CompareOpc = 327; break;
+ case Intrinsic::ppc_altivec_vcmpnezw_p: CompareOpc = 391; break;
+ }
+ isDot = 1;
+ } else
+ return false;
+
+ break;
case Intrinsic::ppc_altivec_vcmpgefp_p: CompareOpc = 454; isDot = 1; break;
case Intrinsic::ppc_altivec_vcmpgtfp_p: CompareOpc = 710; isDot = 1; break;
case Intrinsic::ppc_altivec_vcmpgtsb_p: CompareOpc = 774; isDot = 1; break;
@@ -7772,6 +7804,26 @@
return false;
break;
+ case Intrinsic::ppc_altivec_vcmpneb:
+ case Intrinsic::ppc_altivec_vcmpneh:
+ case Intrinsic::ppc_altivec_vcmpnew:
+ case Intrinsic::ppc_altivec_vcmpnezb:
+ case Intrinsic::ppc_altivec_vcmpnezh:
+ case Intrinsic::ppc_altivec_vcmpnezw:
+ if (Subtarget.hasP9Altivec()) {
+ switch (IntrinsicID) {
+ default: llvm_unreachable("Unknown comparison intrinsic.");
+ case Intrinsic::ppc_altivec_vcmpneb: CompareOpc = 7; break;
+ case Intrinsic::ppc_altivec_vcmpneh: CompareOpc = 71; break;
+ case Intrinsic::ppc_altivec_vcmpnew: CompareOpc = 135; break;
+ case Intrinsic::ppc_altivec_vcmpnezb: CompareOpc = 263; break;
+ case Intrinsic::ppc_altivec_vcmpnezh: CompareOpc = 327; break;
+ case Intrinsic::ppc_altivec_vcmpnezw: CompareOpc = 391; break;
+ }
+ isDot = 0;
+ } else
+ return false;
+ break;
case Intrinsic::ppc_altivec_vcmpgefp: CompareOpc = 454; isDot = 0; break;
case Intrinsic::ppc_altivec_vcmpgtfp: CompareOpc = 710; isDot = 0; break;
case Intrinsic::ppc_altivec_vcmpgtsb: CompareOpc = 774; isDot = 0; break;