diff options
-rw-r--r-- | include/llvm/IR/Intrinsics.h | 2 | ||||
-rw-r--r-- | include/llvm/IR/IntrinsicsPowerPC.td | 20 | ||||
-rw-r--r-- | lib/IR/Function.cpp | 8 | ||||
-rw-r--r-- | lib/Target/PowerPC/PPCInstrVSX.td | 31 | ||||
-rw-r--r-- | test/CodeGen/PowerPC/builtins-ppc-p9-f128.ll | 82 | ||||
-rw-r--r-- | utils/TableGen/IntrinsicEmitter.cpp | 4 |
6 files changed, 138 insertions, 9 deletions
diff --git a/include/llvm/IR/Intrinsics.h b/include/llvm/IR/Intrinsics.h index 50d2a80032c..e1e17f983ff 100644 --- a/include/llvm/IR/Intrinsics.h +++ b/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/include/llvm/IR/IntrinsicsPowerPC.td b/include/llvm/IR/IntrinsicsPowerPC.td index a302d5726aa..99518f34e3d 100644 --- a/include/llvm/IR/IntrinsicsPowerPC.td +++ b/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/lib/IR/Function.cpp b/lib/IR/Function.cpp index db3708943d6..49582c4debc 100644 --- a/lib/IR/Function.cpp +++ b/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/lib/Target/PowerPC/PPCInstrVSX.td b/lib/Target/PowerPC/PPCInstrVSX.td index 3bdf9d8737a..c3e995fe06b 100644 --- a/lib/Target/PowerPC/PPCInstrVSX.td +++ b/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/test/CodeGen/PowerPC/builtins-ppc-p9-f128.ll b/test/CodeGen/PowerPC/builtins-ppc-p9-f128.ll new file mode 100644 index 00000000000..fa40fa2db31 --- /dev/null +++ b/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/utils/TableGen/IntrinsicEmitter.cpp b/utils/TableGen/IntrinsicEmitter.cpp index 65d74ef90a4..06e44e3b57c 100644 --- a/utils/TableGen/IntrinsicEmitter.cpp +++ b/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); |