diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/include/llvm/IR/Intrinsics.h | 2 | ||||
| -rw-r--r-- | llvm/include/llvm/IR/IntrinsicsPowerPC.td | 20 | ||||
| -rw-r--r-- | llvm/lib/IR/Function.cpp | 8 | ||||
| -rw-r--r-- | llvm/lib/Target/PowerPC/PPCInstrVSX.td | 31 | ||||
| -rw-r--r-- | llvm/test/CodeGen/PowerPC/builtins-ppc-p9-f128.ll | 82 | ||||
| -rw-r--r-- | llvm/utils/TableGen/IntrinsicEmitter.cpp | 4 | 
6 files changed, 138 insertions, 9 deletions
diff --git a/llvm/include/llvm/IR/Intrinsics.h b/llvm/include/llvm/IR/Intrinsics.h index 50d2a80032c..e1e17f983ff 100644 --- a/llvm/include/llvm/IR/Intrinsics.h +++ b/llvm/include/llvm/IR/Intrinsics.h @@ -97,7 +97,7 @@ namespace Intrinsic {    /// intrinsic. This is returned by getIntrinsicInfoTableEntries.    struct IITDescriptor {      enum IITDescriptorKind { -      Void, VarArg, MMX, Token, Metadata, Half, Float, Double, +      Void, VarArg, MMX, Token, Metadata, Half, Float, Double, Quad,        Integer, Vector, Pointer, Struct,        Argument, ExtendArgument, TruncArgument, HalfVecArgument,        SameVecWidthArgument, PtrToArgument, PtrToElt, VecOfAnyPtrsToElt diff --git a/llvm/include/llvm/IR/IntrinsicsPowerPC.td b/llvm/include/llvm/IR/IntrinsicsPowerPC.td index a302d5726aa..99518f34e3d 100644 --- a/llvm/include/llvm/IR/IntrinsicsPowerPC.td +++ b/llvm/include/llvm/IR/IntrinsicsPowerPC.td @@ -61,6 +61,26 @@ let TargetPrefix = "ppc" in {  // All intrinsics start with "llvm.ppc.".    def int_ppc_bpermd : GCCBuiltin<"__builtin_bpermd">,                         Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty],                                   [IntrNoMem]>; + +  def int_ppc_sqrtf128_round_to_odd +      : GCCBuiltin<"__builtin_sqrtf128_round_to_odd">, +        Intrinsic <[llvm_f128_ty], [llvm_f128_ty], [IntrNoMem]>; +  def int_ppc_addf128_round_to_odd +      : GCCBuiltin<"__builtin_addf128_round_to_odd">, +        Intrinsic <[llvm_f128_ty], [llvm_f128_ty,llvm_f128_ty], [IntrNoMem]>; +  def int_ppc_subf128_round_to_odd +      : GCCBuiltin<"__builtin_subf128_round_to_odd">, +        Intrinsic <[llvm_f128_ty], [llvm_f128_ty,llvm_f128_ty], [IntrNoMem]>; +  def int_ppc_mulf128_round_to_odd +      : GCCBuiltin<"__builtin_mulf128_round_to_odd">, +        Intrinsic <[llvm_f128_ty], [llvm_f128_ty,llvm_f128_ty], [IntrNoMem]>; +  def int_ppc_divf128_round_to_odd +      : GCCBuiltin<"__builtin_divf128_round_to_odd">, +        Intrinsic <[llvm_f128_ty], [llvm_f128_ty,llvm_f128_ty], [IntrNoMem]>; +  def int_ppc_fmaf128_round_to_odd +      : GCCBuiltin<"__builtin_fmaf128_round_to_odd">, +        Intrinsic <[llvm_f128_ty], [llvm_f128_ty,llvm_f128_ty,llvm_f128_ty], [IntrNoMem]>; +  } diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp index db3708943d6..49582c4debc 100644 --- a/llvm/lib/IR/Function.cpp +++ b/llvm/lib/IR/Function.cpp @@ -673,7 +673,8 @@ enum IIT_Info {    IIT_V1024 = 37,    IIT_STRUCT6 = 38,    IIT_STRUCT7 = 39, -  IIT_STRUCT8 = 40 +  IIT_STRUCT8 = 40, +  IIT_F128 = 41  };  static void DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos, @@ -708,6 +709,9 @@ static void DecodeIITType(unsigned &NextElt, ArrayRef<unsigned char> Infos,    case IIT_F64:      OutputTable.push_back(IITDescriptor::get(IITDescriptor::Double, 0));      return; +  case IIT_F128: +    OutputTable.push_back(IITDescriptor::get(IITDescriptor::Quad, 0)); +    return;    case IIT_I1:      OutputTable.push_back(IITDescriptor::get(IITDescriptor::Integer, 1));      return; @@ -892,6 +896,7 @@ static Type *DecodeFixedType(ArrayRef<Intrinsic::IITDescriptor> &Infos,    case IITDescriptor::Half: return Type::getHalfTy(Context);    case IITDescriptor::Float: return Type::getFloatTy(Context);    case IITDescriptor::Double: return Type::getDoubleTy(Context); +  case IITDescriptor::Quad: return Type::getFP128Ty(Context);    case IITDescriptor::Integer:      return IntegerType::get(Context, D.Integer_Width); @@ -1034,6 +1039,7 @@ bool Intrinsic::matchIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor>      case IITDescriptor::Half: return !Ty->isHalfTy();      case IITDescriptor::Float: return !Ty->isFloatTy();      case IITDescriptor::Double: return !Ty->isDoubleTy(); +    case IITDescriptor::Quad: return !Ty->isFP128Ty();      case IITDescriptor::Integer: return !Ty->isIntegerTy(D.Integer_Width);      case IITDescriptor::Vector: {        VectorType *VT = dyn_cast<VectorType>(Ty); diff --git a/llvm/lib/Target/PowerPC/PPCInstrVSX.td b/llvm/lib/Target/PowerPC/PPCInstrVSX.td index 3bdf9d8737a..c3e995fe06b 100644 --- a/llvm/lib/Target/PowerPC/PPCInstrVSX.td +++ b/llvm/lib/Target/PowerPC/PPCInstrVSX.td @@ -2451,30 +2451,49 @@ let AddedComplexity = 400, Predicates = [HasP9Vector] in {    let isCommutable = 1 in {    def XSADDQP   : X_VT5_VA5_VB5   <63,   4, "xsaddqp",                                     [(set f128:$vT, (fadd f128:$vA, f128:$vB))]>; -  def XSADDQPO  : X_VT5_VA5_VB5_Ro<63,   4, "xsaddqpo", []>; +  def XSADDQPO : X_VT5_VA5_VB5_Ro<63, 4, "xsaddqpo", +                                  [(set f128:$vT, +                                  (int_ppc_addf128_round_to_odd +                                  f128:$vA, f128:$vB))]>;    def XSMULQP   : X_VT5_VA5_VB5   <63,  36, "xsmulqp",                                     [(set f128:$vT, (fmul f128:$vA, f128:$vB))]>; -  def XSMULQPO  : X_VT5_VA5_VB5_Ro<63,  36, "xsmulqpo", []>; +  def XSMULQPO : X_VT5_VA5_VB5_Ro<63, 36, "xsmulqpo", +                                  [(set f128:$vT, +                                  (int_ppc_mulf128_round_to_odd +                                  f128:$vA, f128:$vB))]>;    }    def XSSUBQP   : X_VT5_VA5_VB5   <63, 516, "xssubqp" ,                                     [(set f128:$vT, (fsub f128:$vA, f128:$vB))]>; -  def XSSUBQPO  : X_VT5_VA5_VB5_Ro<63, 516, "xssubqpo", []>; +  def XSSUBQPO : X_VT5_VA5_VB5_Ro<63, 516, "xssubqpo", +                                  [(set f128:$vT, +                                  (int_ppc_subf128_round_to_odd +                                  f128:$vA, f128:$vB))]>;    def XSDIVQP   : X_VT5_VA5_VB5   <63, 548, "xsdivqp",                                     [(set f128:$vT, (fdiv f128:$vA, f128:$vB))]>; -  def XSDIVQPO  : X_VT5_VA5_VB5_Ro<63, 548, "xsdivqpo", []>; +  def XSDIVQPO : X_VT5_VA5_VB5_Ro<63, 548, "xsdivqpo", +                                  [(set f128:$vT, +                                  (int_ppc_divf128_round_to_odd +                                  f128:$vA, f128:$vB))]>;    // Square-Root    def XSSQRTQP  : X_VT5_XO5_VB5   <63, 27, 804, "xssqrtqp",                                     [(set f128:$vT, (fsqrt f128:$vB))]>; -  def XSSQRTQPO : X_VT5_XO5_VB5_Ro<63, 27, 804, "xssqrtqpo", []>; +  def XSSQRTQPO : X_VT5_XO5_VB5_Ro<63, 27, 804, "xssqrtqpo", +                                  [(set f128:$vT, +                                  (int_ppc_sqrtf128_round_to_odd f128:$vB))]>;    // (Negative) Multiply-{Add/Subtract}    def XSMADDQP : X_VT5_VA5_VB5_FMA <63, 388, "xsmaddqp",                                      [(set f128:$vT,                                            (fma f128:$vA, f128:$vB,                                                 f128:$vTi))]>; -  def XSMADDQPO : X_VT5_VA5_VB5_FMA_Ro<63, 388, "xsmaddqpo" , []>; + +  def XSMADDQPO : X_VT5_VA5_VB5_FMA_Ro<63, 388, "xsmaddqpo", +                                      [(set f128:$vT, +                                      (int_ppc_fmaf128_round_to_odd +                                      f128:$vA,f128:$vB,f128:$vTi))]>; +    def XSMSUBQP  : X_VT5_VA5_VB5_FMA   <63, 420, "xsmsubqp"  ,                                         [(set f128:$vT,                                               (fma f128:$vA, f128:$vB, diff --git a/llvm/test/CodeGen/PowerPC/builtins-ppc-p9-f128.ll b/llvm/test/CodeGen/PowerPC/builtins-ppc-p9-f128.ll new file mode 100644 index 00000000000..fa40fa2db31 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/builtins-ppc-p9-f128.ll @@ -0,0 +1,82 @@ +; RUN: llc -verify-machineinstrs -mcpu=pwr9 -enable-ppc-quad-precision \ +; RUN:   -mtriple=powerpc64le-unknown-unknown < %s | FileCheck %s + +@A = common global fp128 0xL00000000000000000000000000000000, align 16 +@B = common global fp128 0xL00000000000000000000000000000000, align 16 +@C = common global fp128 0xL00000000000000000000000000000000, align 16 + +define fp128 @testSqrtOdd() { +entry: +  %0 = load fp128, fp128* @A, align 16 +  %1 = call fp128 @llvm.ppc.sqrtf128.round.to.odd(fp128 %0) +  ret fp128 %1 +; CHECK-LABEL: testSqrtOdd +; CHECK: xssqrtqpo +} + +declare fp128 @llvm.ppc.sqrtf128.round.to.odd(fp128) + +define fp128 @testFMAOdd() { +entry: +  %0 = load fp128, fp128* @A, align 16 +  %1 = load fp128, fp128* @B, align 16 +  %2 = load fp128, fp128* @C, align 16 +  %3 = call fp128 @llvm.ppc.fmaf128.round.to.odd(fp128 %0, fp128 %1, fp128 %2) +  ret fp128 %3 +; CHECK-LABEL: testFMAOdd +; CHECK: xsmaddqpo +} + +declare fp128 @llvm.ppc.fmaf128.round.to.odd(fp128, fp128, fp128) + +define fp128 @testAddOdd() { +entry: +  %0 = load fp128, fp128* @A, align 16 +  %1 = load fp128, fp128* @B, align 16 +  %2 = call fp128 @llvm.ppc.addf128.round.to.odd(fp128 %0, fp128 %1) +  ret fp128 %2 +; CHECK-LABEL: testAddOdd +; CHECK: xsaddqpo +} + +declare fp128 @llvm.ppc.addf128.round.to.odd(fp128, fp128) + +define fp128 @testSubOdd() { +entry: +  %0 = load fp128, fp128* @A, align 16 +  %1 = load fp128, fp128* @B, align 16 +  %2 = call fp128 @llvm.ppc.subf128.round.to.odd(fp128 %0, fp128 %1) +  ret fp128 %2 +; CHECK-LABEL: testSubOdd +; CHECK: xssubqpo +} + +; Function Attrs: nounwind readnone +declare fp128 @llvm.ppc.subf128.round.to.odd(fp128, fp128) + +; Function Attrs: noinline nounwind optnone +define fp128 @testMulOdd() { +entry: +  %0 = load fp128, fp128* @A, align 16 +  %1 = load fp128, fp128* @B, align 16 +  %2 = call fp128 @llvm.ppc.mulf128.round.to.odd(fp128 %0, fp128 %1) +  ret fp128 %2 +; CHECK-LABEL: testMulOdd +; CHECK: xsmulqpo +} + +; Function Attrs: nounwind readnone +declare fp128 @llvm.ppc.mulf128.round.to.odd(fp128, fp128) + +define fp128 @testDivOdd() { +entry: +  %0 = load fp128, fp128* @A, align 16 +  %1 = load fp128, fp128* @B, align 16 +  %2 = call fp128 @llvm.ppc.divf128.round.to.odd(fp128 %0, fp128 %1) +  ret fp128 %2 +; CHECK-LABEL: testDivOdd +; CHECK: xsdivqpo +} + +declare fp128 @llvm.ppc.divf128.round.to.odd(fp128, fp128) + diff --git a/llvm/utils/TableGen/IntrinsicEmitter.cpp b/llvm/utils/TableGen/IntrinsicEmitter.cpp index 65d74ef90a4..06e44e3b57c 100644 --- a/llvm/utils/TableGen/IntrinsicEmitter.cpp +++ b/llvm/utils/TableGen/IntrinsicEmitter.cpp @@ -219,7 +219,8 @@ enum IIT_Info {    IIT_V1024 = 37,    IIT_STRUCT6 = 38,    IIT_STRUCT7 = 39, -  IIT_STRUCT8 = 40 +  IIT_STRUCT8 = 40, +  IIT_F128 = 41  };  static void EncodeFixedValueType(MVT::SimpleValueType VT, @@ -242,6 +243,7 @@ static void EncodeFixedValueType(MVT::SimpleValueType VT,    case MVT::f16: return Sig.push_back(IIT_F16);    case MVT::f32: return Sig.push_back(IIT_F32);    case MVT::f64: return Sig.push_back(IIT_F64); +  case MVT::f128: return Sig.push_back(IIT_F128);    case MVT::token: return Sig.push_back(IIT_TOKEN);    case MVT::Metadata: return Sig.push_back(IIT_METADATA);    case MVT::x86mmx: return Sig.push_back(IIT_MMX);  | 

