Index: lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp =================================================================== --- lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp +++ lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp @@ -292,6 +292,26 @@ switch (Op.getOpcode()) { default: return TranslateLegalizeResults(Op, Result); + case ISD::STRICT_FSQRT: + case ISD::STRICT_FMA: + case ISD::STRICT_FPOW: + case ISD::STRICT_FPOWI: + case ISD::STRICT_FSIN: + case ISD::STRICT_FCOS: + case ISD::STRICT_FEXP: + case ISD::STRICT_FEXP2: + case ISD::STRICT_FLOG: + case ISD::STRICT_FLOG10: + case ISD::STRICT_FLOG2: + case ISD::STRICT_FRINT: + case ISD::STRICT_FNEARBYINT: + // These pseudo-ops get legalized as if they were their non-strict + // equivalent. For instance, if ISD::FSQRT is legal then ISD::STRICT_FSQRT + // is also legal, but if ISD::FSQRT requires expansion then so does + // ISD::STRICT_FSQRT. + Node = DAG.mutateStrictFPToFP(Node); + QueryType = Node->getValueType(0); + break; case ISD::ADD: case ISD::SUB: case ISD::MUL: Index: test/CodeGen/X86/vector-constrained-fp-intrinsics.ll =================================================================== --- test/CodeGen/X86/vector-constrained-fp-intrinsics.ll +++ test/CodeGen/X86/vector-constrained-fp-intrinsics.ll @@ -0,0 +1,165 @@ +; RUN: llc -O3 -mtriple=x86_64-pc-linux < %s | FileCheck --check-prefix=COMMON --check-prefix=NO-FMA --check-prefix=FMACALL64 --check-prefix=FMACALL32 %s +; RUN: llc -O3 -mtriple=x86_64-pc-linux -mattr=+fma < %s | FileCheck -check-prefix=COMMON --check-prefix=HAS-FMA --check-prefix=FMA64 --check-prefix=FMA32 %s + +; CHECK-LABEL: constrained_vector_fdiv +; COMMON: divpd +define <2 x double> @constrained_vector_fdiv() { +entry: + %div = call <2 x double> @llvm.experimental.constrained.fdiv.v2f64( + <2 x double> , + <2 x double> , + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret <2 x double> %div +} + +; CHECK-LABEL: constrained_vector_fmul +; COMMON: mulpd +define <2 x double> @constrained_vector_fmul(<2 x double> %a) { +entry: + %mul = call <2 x double> @llvm.experimental.constrained.fmul.v2f64( + <2 x double> , + <2 x double> , + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret <2 x double> %mul +} + +; CHECK-LABEL: constrained_vector_fadd +; COMMON: addpd +define <2 x double> @constrained_vector_fadd() { +entry: + %add = call <2 x double> @llvm.experimental.constrained.fadd.v2f64( + <2 x double> , + <2 x double> , + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret <2 x double> %add +} + +; CHECK-LABEL: constrained_vector_fsub +; COMMON: subpd +define <2 x double> @constrained_vector_fsub() { +entry: + %sub = call <2 x double> @llvm.experimental.constrained.fsub.v2f64( + <2 x double> , + <2 x double> , + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret <2 x double> %sub +} + +; CHECK-LABEL: constrained_vector_sqrt +; COMMON: sqrtpd +define <2 x double> @constrained_vector_sqrt() { +entry: + %sqrt = call <2 x double> @llvm.experimental.constrained.sqrt.v2f64( + <2 x double> , + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret <2 x double> %sqrt +} + +; CHECK-LABEL: constrained_vector_pow +; COMMON: pow +define <2 x double> @constrained_vector_pow() { +entry: + %pow = call <2 x double> @llvm.experimental.constrained.pow.v2f64( + <2 x double> , + <2 x double> , + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret <2 x double> %pow +} + +; CHECK-LABEL: constrained_vector_sin +; COMMON: sin +define <2 x double> @constrained_vector_sin() { +entry: + %sin = call <2 x double> @llvm.experimental.constrained.sin.v2f64( + <2 x double> , + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret <2 x double> %sin +} + +; CHECK-LABEL: constrained_vector_cos +; COMMON: cos +define <2 x double> @constrained_vector_cos() { +entry: + %cos = call <2 x double> @llvm.experimental.constrained.cos.v2f64( + <2 x double> , + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret <2 x double> %cos +} + +; CHECK-LABEL: constrained_vector_exp +; COMMON: exp +define <2 x double> @constrained_vector_exp() { +entry: + %exp = call <2 x double> @llvm.experimental.constrained.exp.v2f64( + <2 x double> , + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret <2 x double> %exp +} + +; CHECK-LABEL: constrained_vector_exp2 +; COMMON: exp2 +define <2 x double> @constrained_vector_exp2() { +entry: + %exp2 = call <2 x double> @llvm.experimental.constrained.exp2.v2f64( + <2 x double> , + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret <2 x double> %exp2 +} + +; CHECK-LABEL: constrained_vector_log +; COMMON: log +define <2 x double> @constrained_vector_log() { +entry: + %log = call <2 x double> @llvm.experimental.constrained.log.v2f64( + <2 x double> , + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret <2 x double> %log +} + +; CHECK-LABEL: constrained_vector_log10 +; COMMON: log10 +define <2 x double> @constrained_vector_log10() { +entry: + %log10 = call <2 x double> @llvm.experimental.constrained.log10.v2f64( + <2 x double> , + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret <2 x double> %log10 +} + +; CHECK-LABEL: constrained_vector_log2 +; COMMON: log2 +define <2 x double> @constrained_vector_log2() { +entry: + %log2 = call <2 x double> @llvm.experimental.constrained.log2.v2f64( + <2 x double> , + metadata !"round.dynamic", + metadata !"fpexcept.strict") + ret <2 x double> %log2 +} + +declare <2 x double> @llvm.experimental.constrained.fdiv.v2f64(<2 x double>, <2 x double>, metadata, metadata) +declare <2 x double> @llvm.experimental.constrained.fmul.v2f64(<2 x double>, <2 x double>, metadata, metadata) +declare <2 x double> @llvm.experimental.constrained.fadd.v2f64(<2 x double>, <2 x double>, metadata, metadata) +declare <2 x double> @llvm.experimental.constrained.fsub.v2f64(<2 x double>, <2 x double>, metadata, metadata) +declare <2 x double> @llvm.experimental.constrained.sqrt.v2f64(<2 x double>, metadata, metadata) +declare <2 x double> @llvm.experimental.constrained.pow.v2f64(<2 x double>, <2 x double>, metadata, metadata) +declare <2 x double> @llvm.experimental.constrained.sin.v2f64(<2 x double>, metadata, metadata) +declare <2 x double> @llvm.experimental.constrained.cos.v2f64(<2 x double>, metadata, metadata) +declare <2 x double> @llvm.experimental.constrained.exp.v2f64(<2 x double>, metadata, metadata) +declare <2 x double> @llvm.experimental.constrained.exp2.v2f64(<2 x double>, metadata, metadata) +declare <2 x double> @llvm.experimental.constrained.log.v2f64(<2 x double>, metadata, metadata) +declare <2 x double> @llvm.experimental.constrained.log10.v2f64(<2 x double>, metadata, metadata) +declare <2 x double> @llvm.experimental.constrained.log2.v2f64(<2 x double>, metadata, metadata) +