diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -613,6 +613,17 @@ : getLongFractScale() + 1; } + // Determine whether fma is present in target-features + virtual bool hasFMA() const { + if(getTriple().isX86()) { + std::vector targetFeature(getTargetOpts().Features); + if(std::find(targetFeature.begin(), targetFeature.end(), "+fma") != targetFeature.end()) + return true; + return false; + } + return true; + } + /// Determine whether the __int128 type is supported on this target. virtual bool hasInt128Type() const { return (getPointerWidth(LangAS::Default) >= 64) || diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -3796,6 +3796,10 @@ // Check whether this op is marked as fusable. if (!op.FPFeatures.allowFPContractWithinStatement()) return nullptr; + else if(op.FPFeatures.allowFPContractWithinStatement()){ + if(!CGF.getTarget().hasFMA()) + return nullptr; + } Value *LHS = op.LHS; Value *RHS = op.RHS; diff --git a/clang/test/CodeGen/X86/fexcess-precision-bfloat16.c b/clang/test/CodeGen/X86/fexcess-precision-bfloat16.c --- a/clang/test/CodeGen/X86/fexcess-precision-bfloat16.c +++ b/clang/test/CodeGen/X86/fexcess-precision-bfloat16.c @@ -1,173 +1,173 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -fbfloat16-excess-precision=fast -emit-llvm -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-EXT %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -fbfloat16-excess-precision=fast -target-feature +fullbf16 \ // RUN: -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-NO-EXT %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -fbfloat16-excess-precision=standard -emit-llvm -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-EXT %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -fbfloat16-excess-precision=standard -target-feature +fullbf16 \ // RUN: -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-NO-EXT %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -fbfloat16-excess-precision=none -emit-llvm -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-NO-EXT %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -fbfloat16-excess-precision=none -target-feature +fullbf16 \ // RUN: -emit-llvm -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-NO-EXT %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -fbfloat16-excess-precision=fast \ // RUN: -emit-llvm -ffp-eval-method=source -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-EXT %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -fbfloat16-excess-precision=fast -target-feature +fullbf16 \ // RUN: -emit-llvm -ffp-eval-method=source -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-NO-EXT %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -fbfloat16-excess-precision=standard \ // RUN: -emit-llvm -ffp-eval-method=source -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-EXT %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -fbfloat16-excess-precision=standard -target-feature +fullbf16 \ // RUN: -emit-llvm -ffp-eval-method=source -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-NO-EXT %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -fbfloat16-excess-precision=none \ // RUN: -emit-llvm -ffp-eval-method=source -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-NO-EXT %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -fbfloat16-excess-precision=none -target-feature +fullbf16 \ // RUN: -emit-llvm -ffp-eval-method=source -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-NO-EXT %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -fbfloat16-excess-precision=fast \ // RUN: -emit-llvm -ffp-eval-method=double -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-EXT-DBL %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -fbfloat16-excess-precision=fast -target-feature +fullbf16 \ // RUN: -emit-llvm -ffp-eval-method=double -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-EXT-DBL %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -fbfloat16-excess-precision=standard \ // RUN: -emit-llvm -ffp-eval-method=double -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-EXT-DBL %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -fbfloat16-excess-precision=standard -target-feature +fullbf16 \ // RUN: -emit-llvm -ffp-eval-method=double -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-EXT-DBL %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -fbfloat16-excess-precision=none \ // RUN: -emit-llvm -ffp-eval-method=double -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-EXT-DBL %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -fbfloat16-excess-precision=none -target-feature +fullbf16 \ // RUN: -emit-llvm -ffp-eval-method=double -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-EXT-DBL %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -fbfloat16-excess-precision=fast \ // RUN: -emit-llvm -ffp-eval-method=extended -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-EXT-FP80 %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -fbfloat16-excess-precision=fast -target-feature +fullbf16 \ // RUN: -emit-llvm -ffp-eval-method=extended -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-EXT-FP80 %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -fbfloat16-excess-precision=standard \ // RUN: -emit-llvm -ffp-eval-method=extended -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-EXT-FP80 %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -fbfloat16-excess-precision=standard -target-feature +fullbf16 \ // RUN: -emit-llvm -ffp-eval-method=extended -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-EXT-FP80 %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -fbfloat16-excess-precision=none \ // RUN: -emit-llvm -ffp-eval-method=extended -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-EXT-FP80 %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -fbfloat16-excess-precision=none -target-feature +fullbf16 \ // RUN: -emit-llvm -ffp-eval-method=extended -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-EXT-FP80 %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -fbfloat16-excess-precision=none \ // RUN: -ffp-contract=on -emit-llvm -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-CONTRACT %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -fbfloat16-excess-precision=none -target-feature +fullbf16 \ // RUN: -ffp-contract=on -emit-llvm -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-CONTRACT %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -fbfloat16-excess-precision=none \ // RUN: -fmath-errno -ffp-contract=on -fno-rounding-math \ // RUN: -ffp-eval-method=source -emit-llvm -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-CONTRACT %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -fbfloat16-excess-precision=none -target-feature +fullbf16 \ // RUN: -fmath-errno -ffp-contract=on -fno-rounding-math \ // RUN: -ffp-eval-method=source -emit-llvm -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-CONTRACT %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -fbfloat16-excess-precision=none \ // RUN: -fmath-errno -ffp-contract=on -fno-rounding-math \ // RUN: -ffp-eval-method=double -emit-llvm -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-CONTRACT-DBL %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -fbfloat16-excess-precision=none -target-feature +fullbf16 \ // RUN: -fmath-errno -ffp-contract=on -fno-rounding-math \ // RUN: -ffp-eval-method=double -emit-llvm -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-CONTRACT-DBL %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -fbfloat16-excess-precision=none \ // RUN: -fmath-errno -ffp-contract=on -fno-rounding-math \ // RUN: -ffp-eval-method=extended -emit-llvm -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-CONTRACT-EXT %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -fbfloat16-excess-precision=none -target-feature +fullbf16 \ // RUN: -fmath-errno -ffp-contract=on -fno-rounding-math \ // RUN: -ffp-eval-method=extended -emit-llvm -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-CONTRACT-EXT %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -fbfloat16-excess-precision=none \ // RUN: -fapprox-func -fmath-errno -fno-signed-zeros -mreassociate \ // RUN: -freciprocal-math -ffp-contract=on -fno-rounding-math \ // RUN: -funsafe-math-optimizations -emit-llvm -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-UNSAFE %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -fbfloat16-excess-precision=none -target-feature +fullbf16 \ // RUN: -fapprox-func -fmath-errno -fno-signed-zeros -mreassociate \ // RUN: -freciprocal-math -ffp-contract=on -fno-rounding-math \ diff --git a/clang/test/CodeGen/X86/fexcess-precision.c b/clang/test/CodeGen/X86/fexcess-precision.c --- a/clang/test/CodeGen/X86/fexcess-precision.c +++ b/clang/test/CodeGen/X86/fexcess-precision.c @@ -1,347 +1,356 @@ -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma\ // RUN: -ffloat16-excess-precision=fast -emit-llvm -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-EXT %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -ffloat16-excess-precision=fast -target-feature +avx512fp16 \ // RUN: -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-NO-EXT %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -ffloat16-excess-precision=standard -emit-llvm -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-EXT %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -ffloat16-excess-precision=standard -target-feature +avx512fp16 \ // RUN: -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-NO-EXT %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -ffloat16-excess-precision=none -emit-llvm -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-NO-EXT %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -ffloat16-excess-precision=none -target-feature +avx512fp16 \ // RUN: -emit-llvm -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-NO-EXT %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -ffloat16-excess-precision=fast \ // RUN: -emit-llvm -ffp-eval-method=source -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-EXT %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -ffloat16-excess-precision=fast -target-feature +avx512fp16 \ // RUN: -emit-llvm -ffp-eval-method=source -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-NO-EXT %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -ffloat16-excess-precision=standard \ // RUN: -emit-llvm -ffp-eval-method=source -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-EXT %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -ffloat16-excess-precision=standard -target-feature +avx512fp16 \ // RUN: -emit-llvm -ffp-eval-method=source -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-NO-EXT %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -ffloat16-excess-precision=none \ // RUN: -emit-llvm -ffp-eval-method=source -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-NO-EXT %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -ffloat16-excess-precision=none -target-feature +avx512fp16 \ // RUN: -emit-llvm -ffp-eval-method=source -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-NO-EXT %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -ffloat16-excess-precision=fast \ // RUN: -emit-llvm -ffp-eval-method=double -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-EXT-DBL %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -ffloat16-excess-precision=fast -target-feature +avx512fp16 \ // RUN: -emit-llvm -ffp-eval-method=double -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-EXT-DBL %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -ffloat16-excess-precision=standard \ // RUN: -emit-llvm -ffp-eval-method=double -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-EXT-DBL %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -ffloat16-excess-precision=standard -target-feature +avx512fp16 \ // RUN: -emit-llvm -ffp-eval-method=double -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-EXT-DBL %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -ffloat16-excess-precision=none \ // RUN: -emit-llvm -ffp-eval-method=double -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-EXT-DBL %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -ffloat16-excess-precision=none -target-feature +avx512fp16 \ // RUN: -emit-llvm -ffp-eval-method=double -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-EXT-DBL %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -ffloat16-excess-precision=fast \ // RUN: -emit-llvm -ffp-eval-method=extended -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-EXT-FP80 %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -ffloat16-excess-precision=fast -target-feature +avx512fp16 \ // RUN: -emit-llvm -ffp-eval-method=extended -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-EXT-FP80 %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -ffloat16-excess-precision=standard \ // RUN: -emit-llvm -ffp-eval-method=extended -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-EXT-FP80 %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -ffloat16-excess-precision=standard -target-feature +avx512fp16 \ // RUN: -emit-llvm -ffp-eval-method=extended -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-EXT-FP80 %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -ffloat16-excess-precision=none \ // RUN: -emit-llvm -ffp-eval-method=extended -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-EXT-FP80 %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -ffloat16-excess-precision=none -target-feature +avx512fp16 \ // RUN: -emit-llvm -ffp-eval-method=extended -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-EXT-FP80 %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -ffloat16-excess-precision=none \ // RUN: -ffp-contract=on -emit-llvm -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-CONTRACT %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -ffloat16-excess-precision=none -target-feature +avx512fp16 \ // RUN: -ffp-contract=on -emit-llvm -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-CONTRACT %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -ffloat16-excess-precision=none \ // RUN: -fmath-errno -ffp-contract=on -fno-rounding-math \ // RUN: -ffp-eval-method=source -emit-llvm -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-CONTRACT %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -ffloat16-excess-precision=none -target-feature +avx512fp16 \ // RUN: -fmath-errno -ffp-contract=on -fno-rounding-math \ // RUN: -ffp-eval-method=source -emit-llvm -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-CONTRACT %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -ffloat16-excess-precision=none \ // RUN: -fmath-errno -ffp-contract=on -fno-rounding-math \ // RUN: -ffp-eval-method=double -emit-llvm -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-CONTRACT-DBL %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma\ // RUN: -ffloat16-excess-precision=none -target-feature +avx512fp16 \ // RUN: -fmath-errno -ffp-contract=on -fno-rounding-math \ // RUN: -ffp-eval-method=double -emit-llvm -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-CONTRACT-DBL %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -ffloat16-excess-precision=none \ // RUN: -fmath-errno -ffp-contract=on -fno-rounding-math \ // RUN: -ffp-eval-method=extended -emit-llvm -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-CONTRACT-EXT %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -ffloat16-excess-precision=none -target-feature +avx512fp16 \ // RUN: -fmath-errno -ffp-contract=on -fno-rounding-math \ // RUN: -ffp-eval-method=extended -emit-llvm -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-CONTRACT-EXT %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -ffloat16-excess-precision=none \ // RUN: -fapprox-func -fmath-errno -fno-signed-zeros -mreassociate \ // RUN: -freciprocal-math -ffp-contract=on -fno-rounding-math \ // RUN: -funsafe-math-optimizations -emit-llvm -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-UNSAFE %s -// RUN: %clang_cc1 -triple x86_64-unknown-unknown \ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -target-feature +fma \ // RUN: -ffloat16-excess-precision=none -target-feature +avx512fp16 \ // RUN: -fapprox-func -fmath-errno -fno-signed-zeros -mreassociate \ // RUN: -freciprocal-math -ffp-contract=on -fno-rounding-math \ // RUN: -funsafe-math-optimizations -emit-llvm -o - %s \ // RUN: | FileCheck -check-prefixes=CHECK-UNSAFE %s -// CHECK-EXT-LABEL: @f( +// CHECK-EXT-LABEL: define dso_local half @f +// CHECK-EXT-SAME: (half noundef [[A:%.*]], half noundef [[B:%.*]], half noundef [[C:%.*]], half noundef [[D:%.*]]) #[[ATTR0:[0-9]+]] { // CHECK-EXT-NEXT: entry: -// CHECK-EXT-NEXT: [[A_ADDR:%.*]] = alloca half -// CHECK-EXT-NEXT: [[B_ADDR:%.*]] = alloca half -// CHECK-EXT-NEXT: [[C_ADDR:%.*]] = alloca half -// CHECK-EXT-NEXT: [[D_ADDR:%.*]] = alloca half -// CHECK-EXT-NEXT: store half [[A:%.*]], ptr [[A_ADDR]] -// CHECK-EXT-NEXT: store half [[B:%.*]], ptr [[B_ADDR]] -// CHECK-EXT-NEXT: store half [[C:%.*]], ptr [[C_ADDR]] -// CHECK-EXT-NEXT: store half [[D:%.*]], ptr [[D_ADDR]] -// CHECK-EXT-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]] +// CHECK-EXT-NEXT: [[A_ADDR:%.*]] = alloca half, align 2 +// CHECK-EXT-NEXT: [[B_ADDR:%.*]] = alloca half, align 2 +// CHECK-EXT-NEXT: [[C_ADDR:%.*]] = alloca half, align 2 +// CHECK-EXT-NEXT: [[D_ADDR:%.*]] = alloca half, align 2 +// CHECK-EXT-NEXT: store half [[A]], ptr [[A_ADDR]], align 2 +// CHECK-EXT-NEXT: store half [[B]], ptr [[B_ADDR]], align 2 +// CHECK-EXT-NEXT: store half [[C]], ptr [[C_ADDR]], align 2 +// CHECK-EXT-NEXT: store half [[D]], ptr [[D_ADDR]], align 2 +// CHECK-EXT-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2 // CHECK-EXT-NEXT: [[EXT:%.*]] = fpext half [[TMP0]] to float -// CHECK-EXT-NEXT: [[TMP1:%.*]] = load half, ptr [[B_ADDR]] +// CHECK-EXT-NEXT: [[TMP1:%.*]] = load half, ptr [[B_ADDR]], align 2 // CHECK-EXT-NEXT: [[EXT1:%.*]] = fpext half [[TMP1]] to float // CHECK-EXT-NEXT: [[MUL:%.*]] = fmul float [[EXT]], [[EXT1]] -// CHECK-EXT-NEXT: [[TMP2:%.*]] = load half, ptr [[C_ADDR]] +// CHECK-EXT-NEXT: [[TMP2:%.*]] = load half, ptr [[C_ADDR]], align 2 // CHECK-EXT-NEXT: [[EXT2:%.*]] = fpext half [[TMP2]] to float -// CHECK-EXT-NEXT: [[TMP3:%.*]] = load half, ptr [[D_ADDR]] +// CHECK-EXT-NEXT: [[TMP3:%.*]] = load half, ptr [[D_ADDR]], align 2 // CHECK-EXT-NEXT: [[EXT3:%.*]] = fpext half [[TMP3]] to float // CHECK-EXT-NEXT: [[MUL4:%.*]] = fmul float [[EXT2]], [[EXT3]] // CHECK-EXT-NEXT: [[ADD:%.*]] = fadd float [[MUL]], [[MUL4]] // CHECK-EXT-NEXT: [[UNPROMOTION:%.*]] = fptrunc float [[ADD]] to half // CHECK-EXT-NEXT: ret half [[UNPROMOTION]] // -// CHECK-NO-EXT-LABEL: @f( +// CHECK-NO-EXT-LABEL: define dso_local half @f +// CHECK-NO-EXT-SAME: (half noundef [[A:%.*]], half noundef [[B:%.*]], half noundef [[C:%.*]], half noundef [[D:%.*]]) #[[ATTR0:[0-9]+]] { // CHECK-NO-EXT-NEXT: entry: -// CHECK-NO-EXT-NEXT: [[A_ADDR:%.*]] = alloca half -// CHECK-NO-EXT-NEXT: [[B_ADDR:%.*]] = alloca half -// CHECK-NO-EXT-NEXT: [[C_ADDR:%.*]] = alloca half -// CHECK-NO-EXT-NEXT: [[D_ADDR:%.*]] = alloca half -// CHECK-NO-EXT-NEXT: store half [[A:%.*]], ptr [[A_ADDR]] -// CHECK-NO-EXT-NEXT: store half [[B:%.*]], ptr [[B_ADDR]] -// CHECK-NO-EXT-NEXT: store half [[C:%.*]], ptr [[C_ADDR]] -// CHECK-NO-EXT-NEXT: store half [[D:%.*]], ptr [[D_ADDR]] -// CHECK-NO-EXT-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]] -// CHECK-NO-EXT-NEXT: [[TMP1:%.*]] = load half, ptr [[B_ADDR]] +// CHECK-NO-EXT-NEXT: [[A_ADDR:%.*]] = alloca half, align 2 +// CHECK-NO-EXT-NEXT: [[B_ADDR:%.*]] = alloca half, align 2 +// CHECK-NO-EXT-NEXT: [[C_ADDR:%.*]] = alloca half, align 2 +// CHECK-NO-EXT-NEXT: [[D_ADDR:%.*]] = alloca half, align 2 +// CHECK-NO-EXT-NEXT: store half [[A]], ptr [[A_ADDR]], align 2 +// CHECK-NO-EXT-NEXT: store half [[B]], ptr [[B_ADDR]], align 2 +// CHECK-NO-EXT-NEXT: store half [[C]], ptr [[C_ADDR]], align 2 +// CHECK-NO-EXT-NEXT: store half [[D]], ptr [[D_ADDR]], align 2 +// CHECK-NO-EXT-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2 +// CHECK-NO-EXT-NEXT: [[TMP1:%.*]] = load half, ptr [[B_ADDR]], align 2 // CHECK-NO-EXT-NEXT: [[MUL:%.*]] = fmul half [[TMP0]], [[TMP1]] -// CHECK-NO-EXT-NEXT: [[TMP2:%.*]] = load half, ptr [[C_ADDR]] -// CHECK-NO-EXT-NEXT: [[TMP3:%.*]] = load half, ptr [[D_ADDR]] +// CHECK-NO-EXT-NEXT: [[TMP2:%.*]] = load half, ptr [[C_ADDR]], align 2 +// CHECK-NO-EXT-NEXT: [[TMP3:%.*]] = load half, ptr [[D_ADDR]], align 2 // CHECK-NO-EXT-NEXT: [[MUL1:%.*]] = fmul half [[TMP2]], [[TMP3]] // CHECK-NO-EXT-NEXT: [[ADD:%.*]] = fadd half [[MUL]], [[MUL1]] // CHECK-NO-EXT-NEXT: ret half [[ADD]] // -// CHECK-EXT-DBL-LABEL: @f( +// CHECK-EXT-DBL-LABEL: define dso_local half @f +// CHECK-EXT-DBL-SAME: (half noundef [[A:%.*]], half noundef [[B:%.*]], half noundef [[C:%.*]], half noundef [[D:%.*]]) #[[ATTR0:[0-9]+]] { // CHECK-EXT-DBL-NEXT: entry: -// CHECK-EXT-DBL-NEXT: [[A_ADDR:%.*]] = alloca half -// CHECK-EXT-DBL-NEXT: [[B_ADDR:%.*]] = alloca half -// CHECK-EXT-DBL-NEXT: [[C_ADDR:%.*]] = alloca half -// CHECK-EXT-DBL-NEXT: [[D_ADDR:%.*]] = alloca half -// CHECK-EXT-DBL-NEXT: store half [[A:%.*]], ptr [[A_ADDR]] -// CHECK-EXT-DBL-NEXT: store half [[B:%.*]], ptr [[B_ADDR]] -// CHECK-EXT-DBL-NEXT: store half [[C:%.*]], ptr [[C_ADDR]] -// CHECK-EXT-DBL-NEXT: store half [[D:%.*]], ptr [[D_ADDR]] -// CHECK-EXT-DBL-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]] +// CHECK-EXT-DBL-NEXT: [[A_ADDR:%.*]] = alloca half, align 2 +// CHECK-EXT-DBL-NEXT: [[B_ADDR:%.*]] = alloca half, align 2 +// CHECK-EXT-DBL-NEXT: [[C_ADDR:%.*]] = alloca half, align 2 +// CHECK-EXT-DBL-NEXT: [[D_ADDR:%.*]] = alloca half, align 2 +// CHECK-EXT-DBL-NEXT: store half [[A]], ptr [[A_ADDR]], align 2 +// CHECK-EXT-DBL-NEXT: store half [[B]], ptr [[B_ADDR]], align 2 +// CHECK-EXT-DBL-NEXT: store half [[C]], ptr [[C_ADDR]], align 2 +// CHECK-EXT-DBL-NEXT: store half [[D]], ptr [[D_ADDR]], align 2 +// CHECK-EXT-DBL-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2 // CHECK-EXT-DBL-NEXT: [[CONV:%.*]] = fpext half [[TMP0]] to double -// CHECK-EXT-DBL-NEXT: [[TMP1:%.*]] = load half, ptr [[B_ADDR]] +// CHECK-EXT-DBL-NEXT: [[TMP1:%.*]] = load half, ptr [[B_ADDR]], align 2 // CHECK-EXT-DBL-NEXT: [[CONV1:%.*]] = fpext half [[TMP1]] to double // CHECK-EXT-DBL-NEXT: [[MUL:%.*]] = fmul double [[CONV]], [[CONV1]] -// CHECK-EXT-DBL-NEXT: [[TMP2:%.*]] = load half, ptr [[C_ADDR]] +// CHECK-EXT-DBL-NEXT: [[TMP2:%.*]] = load half, ptr [[C_ADDR]], align 2 // CHECK-EXT-DBL-NEXT: [[CONV2:%.*]] = fpext half [[TMP2]] to double -// CHECK-EXT-DBL-NEXT: [[TMP3:%.*]] = load half, ptr [[D_ADDR]] +// CHECK-EXT-DBL-NEXT: [[TMP3:%.*]] = load half, ptr [[D_ADDR]], align 2 // CHECK-EXT-DBL-NEXT: [[CONV3:%.*]] = fpext half [[TMP3]] to double // CHECK-EXT-DBL-NEXT: [[MUL4:%.*]] = fmul double [[CONV2]], [[CONV3]] // CHECK-EXT-DBL-NEXT: [[ADD:%.*]] = fadd double [[MUL]], [[MUL4]] // CHECK-EXT-DBL-NEXT: [[CONV5:%.*]] = fptrunc double [[ADD]] to half // CHECK-EXT-DBL-NEXT: ret half [[CONV5]] // -// CHECK-EXT-FP80-LABEL: @f( +// CHECK-EXT-FP80-LABEL: define dso_local half @f +// CHECK-EXT-FP80-SAME: (half noundef [[A:%.*]], half noundef [[B:%.*]], half noundef [[C:%.*]], half noundef [[D:%.*]]) #[[ATTR0:[0-9]+]] { // CHECK-EXT-FP80-NEXT: entry: -// CHECK-EXT-FP80-NEXT: [[A_ADDR:%.*]] = alloca half -// CHECK-EXT-FP80-NEXT: [[B_ADDR:%.*]] = alloca half -// CHECK-EXT-FP80-NEXT: [[C_ADDR:%.*]] = alloca half -// CHECK-EXT-FP80-NEXT: [[D_ADDR:%.*]] = alloca half -// CHECK-EXT-FP80-NEXT: store half [[A:%.*]], ptr [[A_ADDR]] -// CHECK-EXT-FP80-NEXT: store half [[B:%.*]], ptr [[B_ADDR]] -// CHECK-EXT-FP80-NEXT: store half [[C:%.*]], ptr [[C_ADDR]] -// CHECK-EXT-FP80-NEXT: store half [[D:%.*]], ptr [[D_ADDR]] -// CHECK-EXT-FP80-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]] +// CHECK-EXT-FP80-NEXT: [[A_ADDR:%.*]] = alloca half, align 2 +// CHECK-EXT-FP80-NEXT: [[B_ADDR:%.*]] = alloca half, align 2 +// CHECK-EXT-FP80-NEXT: [[C_ADDR:%.*]] = alloca half, align 2 +// CHECK-EXT-FP80-NEXT: [[D_ADDR:%.*]] = alloca half, align 2 +// CHECK-EXT-FP80-NEXT: store half [[A]], ptr [[A_ADDR]], align 2 +// CHECK-EXT-FP80-NEXT: store half [[B]], ptr [[B_ADDR]], align 2 +// CHECK-EXT-FP80-NEXT: store half [[C]], ptr [[C_ADDR]], align 2 +// CHECK-EXT-FP80-NEXT: store half [[D]], ptr [[D_ADDR]], align 2 +// CHECK-EXT-FP80-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2 // CHECK-EXT-FP80-NEXT: [[CONV:%.*]] = fpext half [[TMP0]] to x86_fp80 -// CHECK-EXT-FP80-NEXT: [[TMP1:%.*]] = load half, ptr [[B_ADDR]] +// CHECK-EXT-FP80-NEXT: [[TMP1:%.*]] = load half, ptr [[B_ADDR]], align 2 // CHECK-EXT-FP80-NEXT: [[CONV1:%.*]] = fpext half [[TMP1]] to x86_fp80 // CHECK-EXT-FP80-NEXT: [[MUL:%.*]] = fmul x86_fp80 [[CONV]], [[CONV1]] -// CHECK-EXT-FP80-NEXT: [[TMP2:%.*]] = load half, ptr [[C_ADDR]] +// CHECK-EXT-FP80-NEXT: [[TMP2:%.*]] = load half, ptr [[C_ADDR]], align 2 // CHECK-EXT-FP80-NEXT: [[CONV2:%.*]] = fpext half [[TMP2]] to x86_fp80 -// CHECK-EXT-FP80-NEXT: [[TMP3:%.*]] = load half, ptr [[D_ADDR]] +// CHECK-EXT-FP80-NEXT: [[TMP3:%.*]] = load half, ptr [[D_ADDR]], align 2 // CHECK-EXT-FP80-NEXT: [[CONV3:%.*]] = fpext half [[TMP3]] to x86_fp80 // CHECK-EXT-FP80-NEXT: [[MUL4:%.*]] = fmul x86_fp80 [[CONV2]], [[CONV3]] // CHECK-EXT-FP80-NEXT: [[ADD:%.*]] = fadd x86_fp80 [[MUL]], [[MUL4]] // CHECK-EXT-FP80-NEXT: [[CONV5:%.*]] = fptrunc x86_fp80 [[ADD]] to half // CHECK-EXT-FP80-NEXT: ret half [[CONV5]] // -// CHECK-CONTRACT-LABEL: @f( +// CHECK-CONTRACT-LABEL: define dso_local half @f +// CHECK-CONTRACT-SAME: (half noundef [[A:%.*]], half noundef [[B:%.*]], half noundef [[C:%.*]], half noundef [[D:%.*]]) #[[ATTR0:[0-9]+]] { // CHECK-CONTRACT-NEXT: entry: -// CHECK-CONTRACT-NEXT: [[A_ADDR:%.*]] = alloca half -// CHECK-CONTRACT-NEXT: [[B_ADDR:%.*]] = alloca half -// CHECK-CONTRACT-NEXT: [[C_ADDR:%.*]] = alloca half -// CHECK-CONTRACT-NEXT: [[D_ADDR:%.*]] = alloca half -// CHECK-CONTRACT-NEXT: store half [[A:%.*]], ptr [[A_ADDR]] -// CHECK-CONTRACT-NEXT: store half [[B:%.*]], ptr [[B_ADDR]] -// CHECK-CONTRACT-NEXT: store half [[C:%.*]], ptr [[C_ADDR]] -// CHECK-CONTRACT-NEXT: store half [[D:%.*]], ptr [[D_ADDR]] -// CHECK-CONTRACT-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]] -// CHECK-CONTRACT-NEXT: [[TMP1:%.*]] = load half, ptr [[B_ADDR]] -// CHECK-CONTRACT-NEXT: [[TMP2:%.*]] = load half, ptr [[C_ADDR]] -// CHECK-CONTRACT-NEXT: [[TMP3:%.*]] = load half, ptr [[D_ADDR]] +// CHECK-CONTRACT-NEXT: [[A_ADDR:%.*]] = alloca half, align 2 +// CHECK-CONTRACT-NEXT: [[B_ADDR:%.*]] = alloca half, align 2 +// CHECK-CONTRACT-NEXT: [[C_ADDR:%.*]] = alloca half, align 2 +// CHECK-CONTRACT-NEXT: [[D_ADDR:%.*]] = alloca half, align 2 +// CHECK-CONTRACT-NEXT: store half [[A]], ptr [[A_ADDR]], align 2 +// CHECK-CONTRACT-NEXT: store half [[B]], ptr [[B_ADDR]], align 2 +// CHECK-CONTRACT-NEXT: store half [[C]], ptr [[C_ADDR]], align 2 +// CHECK-CONTRACT-NEXT: store half [[D]], ptr [[D_ADDR]], align 2 +// CHECK-CONTRACT-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2 +// CHECK-CONTRACT-NEXT: [[TMP1:%.*]] = load half, ptr [[B_ADDR]], align 2 +// CHECK-CONTRACT-NEXT: [[TMP2:%.*]] = load half, ptr [[C_ADDR]], align 2 +// CHECK-CONTRACT-NEXT: [[TMP3:%.*]] = load half, ptr [[D_ADDR]], align 2 // CHECK-CONTRACT-NEXT: [[MUL1:%.*]] = fmul half [[TMP2]], [[TMP3]] // CHECK-CONTRACT-NEXT: [[TMP4:%.*]] = call half @llvm.fmuladd.f16(half [[TMP0]], half [[TMP1]], half [[MUL1]]) // CHECK-CONTRACT-NEXT: ret half [[TMP4]] // -// CHECK-CONTRACT-DBL-LABEL: @f( +// CHECK-CONTRACT-DBL-LABEL: define dso_local half @f +// CHECK-CONTRACT-DBL-SAME: (half noundef [[A:%.*]], half noundef [[B:%.*]], half noundef [[C:%.*]], half noundef [[D:%.*]]) #[[ATTR0:[0-9]+]] { // CHECK-CONTRACT-DBL-NEXT: entry: -// CHECK-CONTRACT-DBL-NEXT: [[A_ADDR:%.*]] = alloca half -// CHECK-CONTRACT-DBL-NEXT: [[B_ADDR:%.*]] = alloca half -// CHECK-CONTRACT-DBL-NEXT: [[C_ADDR:%.*]] = alloca half -// CHECK-CONTRACT-DBL-NEXT: [[D_ADDR:%.*]] = alloca half -// CHECK-CONTRACT-DBL-NEXT: store half [[A:%.*]], ptr [[A_ADDR]] -// CHECK-CONTRACT-DBL-NEXT: store half [[B:%.*]], ptr [[B_ADDR]] -// CHECK-CONTRACT-DBL-NEXT: store half [[C:%.*]], ptr [[C_ADDR]] -// CHECK-CONTRACT-DBL-NEXT: store half [[D:%.*]], ptr [[D_ADDR]] -// CHECK-CONTRACT-DBL-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]] +// CHECK-CONTRACT-DBL-NEXT: [[A_ADDR:%.*]] = alloca half, align 2 +// CHECK-CONTRACT-DBL-NEXT: [[B_ADDR:%.*]] = alloca half, align 2 +// CHECK-CONTRACT-DBL-NEXT: [[C_ADDR:%.*]] = alloca half, align 2 +// CHECK-CONTRACT-DBL-NEXT: [[D_ADDR:%.*]] = alloca half, align 2 +// CHECK-CONTRACT-DBL-NEXT: store half [[A]], ptr [[A_ADDR]], align 2 +// CHECK-CONTRACT-DBL-NEXT: store half [[B]], ptr [[B_ADDR]], align 2 +// CHECK-CONTRACT-DBL-NEXT: store half [[C]], ptr [[C_ADDR]], align 2 +// CHECK-CONTRACT-DBL-NEXT: store half [[D]], ptr [[D_ADDR]], align 2 +// CHECK-CONTRACT-DBL-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2 // CHECK-CONTRACT-DBL-NEXT: [[CONV:%.*]] = fpext half [[TMP0]] to double -// CHECK-CONTRACT-DBL-NEXT: [[TMP1:%.*]] = load half, ptr [[B_ADDR]] +// CHECK-CONTRACT-DBL-NEXT: [[TMP1:%.*]] = load half, ptr [[B_ADDR]], align 2 // CHECK-CONTRACT-DBL-NEXT: [[CONV1:%.*]] = fpext half [[TMP1]] to double -// CHECK-CONTRACT-DBL-NEXT: [[TMP2:%.*]] = load half, ptr [[C_ADDR]] +// CHECK-CONTRACT-DBL-NEXT: [[TMP2:%.*]] = load half, ptr [[C_ADDR]], align 2 // CHECK-CONTRACT-DBL-NEXT: [[CONV2:%.*]] = fpext half [[TMP2]] to double -// CHECK-CONTRACT-DBL-NEXT: [[TMP3:%.*]] = load half, ptr [[D_ADDR]] +// CHECK-CONTRACT-DBL-NEXT: [[TMP3:%.*]] = load half, ptr [[D_ADDR]], align 2 // CHECK-CONTRACT-DBL-NEXT: [[CONV3:%.*]] = fpext half [[TMP3]] to double // CHECK-CONTRACT-DBL-NEXT: [[MUL4:%.*]] = fmul double [[CONV2]], [[CONV3]] // CHECK-CONTRACT-DBL-NEXT: [[TMP4:%.*]] = call double @llvm.fmuladd.f64(double [[CONV]], double [[CONV1]], double [[MUL4]]) // CHECK-CONTRACT-DBL-NEXT: [[CONV5:%.*]] = fptrunc double [[TMP4]] to half // CHECK-CONTRACT-DBL-NEXT: ret half [[CONV5]] // -// CHECK-CONTRACT-EXT-LABEL: @f( +// CHECK-CONTRACT-EXT-LABEL: define dso_local half @f +// CHECK-CONTRACT-EXT-SAME: (half noundef [[A:%.*]], half noundef [[B:%.*]], half noundef [[C:%.*]], half noundef [[D:%.*]]) #[[ATTR0:[0-9]+]] { // CHECK-CONTRACT-EXT-NEXT: entry: -// CHECK-CONTRACT-EXT-NEXT: [[A_ADDR:%.*]] = alloca half -// CHECK-CONTRACT-EXT-NEXT: [[B_ADDR:%.*]] = alloca half -// CHECK-CONTRACT-EXT-NEXT: [[C_ADDR:%.*]] = alloca half -// CHECK-CONTRACT-EXT-NEXT: [[D_ADDR:%.*]] = alloca half -// CHECK-CONTRACT-EXT-NEXT: store half [[A:%.*]], ptr [[A_ADDR]] -// CHECK-CONTRACT-EXT-NEXT: store half [[B:%.*]], ptr [[B_ADDR]] -// CHECK-CONTRACT-EXT-NEXT: store half [[C:%.*]], ptr [[C_ADDR]] -// CHECK-CONTRACT-EXT-NEXT: store half [[D:%.*]], ptr [[D_ADDR]] -// CHECK-CONTRACT-EXT-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]] +// CHECK-CONTRACT-EXT-NEXT: [[A_ADDR:%.*]] = alloca half, align 2 +// CHECK-CONTRACT-EXT-NEXT: [[B_ADDR:%.*]] = alloca half, align 2 +// CHECK-CONTRACT-EXT-NEXT: [[C_ADDR:%.*]] = alloca half, align 2 +// CHECK-CONTRACT-EXT-NEXT: [[D_ADDR:%.*]] = alloca half, align 2 +// CHECK-CONTRACT-EXT-NEXT: store half [[A]], ptr [[A_ADDR]], align 2 +// CHECK-CONTRACT-EXT-NEXT: store half [[B]], ptr [[B_ADDR]], align 2 +// CHECK-CONTRACT-EXT-NEXT: store half [[C]], ptr [[C_ADDR]], align 2 +// CHECK-CONTRACT-EXT-NEXT: store half [[D]], ptr [[D_ADDR]], align 2 +// CHECK-CONTRACT-EXT-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2 // CHECK-CONTRACT-EXT-NEXT: [[CONV:%.*]] = fpext half [[TMP0]] to x86_fp80 -// CHECK-CONTRACT-EXT-NEXT: [[TMP1:%.*]] = load half, ptr [[B_ADDR]] +// CHECK-CONTRACT-EXT-NEXT: [[TMP1:%.*]] = load half, ptr [[B_ADDR]], align 2 // CHECK-CONTRACT-EXT-NEXT: [[CONV1:%.*]] = fpext half [[TMP1]] to x86_fp80 -// CHECK-CONTRACT-EXT-NEXT: [[TMP2:%.*]] = load half, ptr [[C_ADDR]] +// CHECK-CONTRACT-EXT-NEXT: [[TMP2:%.*]] = load half, ptr [[C_ADDR]], align 2 // CHECK-CONTRACT-EXT-NEXT: [[CONV2:%.*]] = fpext half [[TMP2]] to x86_fp80 -// CHECK-CONTRACT-EXT-NEXT: [[TMP3:%.*]] = load half, ptr [[D_ADDR]] +// CHECK-CONTRACT-EXT-NEXT: [[TMP3:%.*]] = load half, ptr [[D_ADDR]], align 2 // CHECK-CONTRACT-EXT-NEXT: [[CONV3:%.*]] = fpext half [[TMP3]] to x86_fp80 // CHECK-CONTRACT-EXT-NEXT: [[MUL4:%.*]] = fmul x86_fp80 [[CONV2]], [[CONV3]] // CHECK-CONTRACT-EXT-NEXT: [[TMP4:%.*]] = call x86_fp80 @llvm.fmuladd.f80(x86_fp80 [[CONV]], x86_fp80 [[CONV1]], x86_fp80 [[MUL4]]) // CHECK-CONTRACT-EXT-NEXT: [[CONV5:%.*]] = fptrunc x86_fp80 [[TMP4]] to half // CHECK-CONTRACT-EXT-NEXT: ret half [[CONV5]] // -// CHECK-UNSAFE-LABEL: @f( +// CHECK-UNSAFE-LABEL: define dso_local half @f +// CHECK-UNSAFE-SAME: (half noundef [[A:%.*]], half noundef [[B:%.*]], half noundef [[C:%.*]], half noundef [[D:%.*]]) #[[ATTR0:[0-9]+]] { // CHECK-UNSAFE-NEXT: entry: -// CHECK-UNSAFE-NEXT: [[A_ADDR:%.*]] = alloca half -// CHECK-UNSAFE-NEXT: [[B_ADDR:%.*]] = alloca half -// CHECK-UNSAFE-NEXT: [[C_ADDR:%.*]] = alloca half -// CHECK-UNSAFE-NEXT: [[D_ADDR:%.*]] = alloca half -// CHECK-UNSAFE-NEXT: store half [[A:%.*]], ptr [[A_ADDR]] -// CHECK-UNSAFE-NEXT: store half [[B:%.*]], ptr [[B_ADDR]] -// CHECK-UNSAFE-NEXT: store half [[C:%.*]], ptr [[C_ADDR]] -// CHECK-UNSAFE-NEXT: store half [[D:%.*]], ptr [[D_ADDR]] -// CHECK-UNSAFE-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]] -// CHECK-UNSAFE-NEXT: [[TMP1:%.*]] = load half, ptr [[B_ADDR]] -// CHECK-UNSAFE-NEXT: [[TMP2:%.*]] = load half, ptr [[C_ADDR]] -// CHECK-UNSAFE-NEXT: [[TMP3:%.*]] = load half, ptr [[D_ADDR]] +// CHECK-UNSAFE-NEXT: [[A_ADDR:%.*]] = alloca half, align 2 +// CHECK-UNSAFE-NEXT: [[B_ADDR:%.*]] = alloca half, align 2 +// CHECK-UNSAFE-NEXT: [[C_ADDR:%.*]] = alloca half, align 2 +// CHECK-UNSAFE-NEXT: [[D_ADDR:%.*]] = alloca half, align 2 +// CHECK-UNSAFE-NEXT: store half [[A]], ptr [[A_ADDR]], align 2 +// CHECK-UNSAFE-NEXT: store half [[B]], ptr [[B_ADDR]], align 2 +// CHECK-UNSAFE-NEXT: store half [[C]], ptr [[C_ADDR]], align 2 +// CHECK-UNSAFE-NEXT: store half [[D]], ptr [[D_ADDR]], align 2 +// CHECK-UNSAFE-NEXT: [[TMP0:%.*]] = load half, ptr [[A_ADDR]], align 2 +// CHECK-UNSAFE-NEXT: [[TMP1:%.*]] = load half, ptr [[B_ADDR]], align 2 +// CHECK-UNSAFE-NEXT: [[TMP2:%.*]] = load half, ptr [[C_ADDR]], align 2 +// CHECK-UNSAFE-NEXT: [[TMP3:%.*]] = load half, ptr [[D_ADDR]], align 2 // CHECK-UNSAFE-NEXT: [[MUL1:%.*]] = fmul reassoc nsz arcp afn half [[TMP2]], [[TMP3]] // CHECK-UNSAFE-NEXT: [[TMP4:%.*]] = call reassoc nsz arcp afn half @llvm.fmuladd.f16(half [[TMP0]], half [[TMP1]], half [[MUL1]]) // CHECK-UNSAFE-NEXT: ret half [[TMP4]] @@ -350,35 +359,43 @@ return a * b + c * d; } -// CHECK-EXT-LABEL: @getFEM( +// CHECK-EXT-LABEL: define dso_local i32 @getFEM +// CHECK-EXT-SAME: () #[[ATTR0]] { // CHECK-EXT-NEXT: entry: // CHECK-EXT-NEXT: ret i32 0 // -// CHECK-NO-EXT-LABEL: @getFEM( +// CHECK-NO-EXT-LABEL: define dso_local i32 @getFEM +// CHECK-NO-EXT-SAME: () #[[ATTR0]] { // CHECK-NO-EXT-NEXT: entry: // CHECK-NO-EXT-NEXT: ret i32 0 // -// CHECK-EXT-DBL-LABEL: @getFEM( +// CHECK-EXT-DBL-LABEL: define dso_local i32 @getFEM +// CHECK-EXT-DBL-SAME: () #[[ATTR0]] { // CHECK-EXT-DBL-NEXT: entry: // CHECK-EXT-DBL-NEXT: ret i32 1 // -// CHECK-EXT-FP80-LABEL: @getFEM( +// CHECK-EXT-FP80-LABEL: define dso_local i32 @getFEM +// CHECK-EXT-FP80-SAME: () #[[ATTR0]] { // CHECK-EXT-FP80-NEXT: entry: // CHECK-EXT-FP80-NEXT: ret i32 2 // -// CHECK-CONTRACT-LABEL: @getFEM( +// CHECK-CONTRACT-LABEL: define dso_local i32 @getFEM +// CHECK-CONTRACT-SAME: () #[[ATTR0]] { // CHECK-CONTRACT-NEXT: entry: // CHECK-CONTRACT-NEXT: ret i32 0 // -// CHECK-CONTRACT-DBL-LABEL: @getFEM( +// CHECK-CONTRACT-DBL-LABEL: define dso_local i32 @getFEM +// CHECK-CONTRACT-DBL-SAME: () #[[ATTR0]] { // CHECK-CONTRACT-DBL-NEXT: entry: // CHECK-CONTRACT-DBL-NEXT: ret i32 1 // -// CHECK-CONTRACT-EXT-LABEL: @getFEM( +// CHECK-CONTRACT-EXT-LABEL: define dso_local i32 @getFEM +// CHECK-CONTRACT-EXT-SAME: () #[[ATTR0]] { // CHECK-CONTRACT-EXT-NEXT: entry: // CHECK-CONTRACT-EXT-NEXT: ret i32 2 // -// CHECK-UNSAFE-LABEL: @getFEM( +// CHECK-UNSAFE-LABEL: define dso_local i32 @getFEM +// CHECK-UNSAFE-SAME: () #[[ATTR0]] { // CHECK-UNSAFE-NEXT: entry: // CHECK-UNSAFE-NEXT: ret i32 0 // diff --git a/clang/test/CodeGen/X86/fma-intrinsics.c b/clang/test/CodeGen/X86/fma-intrinsics.c new file mode 100644 --- /dev/null +++ b/clang/test/CodeGen/X86/fma-intrinsics.c @@ -0,0 +1,38 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 + +// RUN: %clang -target x86_64 -march=nehalem -emit-llvm -S %s -o - | FileCheck %s + +// RUN: %clang -target x86_64 -march=skylake -emit-llvm -S %s -o - | FileCheck -check-prefixes=CHECK-NO-EXT %s + +// CHECK-LABEL: define dso_local double @testFma +// CHECK-SAME: (double noundef [[TMP0:%.*]], double noundef [[TMP1:%.*]], double noundef [[TMP2:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: [[TMP4:%.*]] = alloca double, align 8 +// CHECK-NEXT: [[TMP5:%.*]] = alloca double, align 8 +// CHECK-NEXT: [[TMP6:%.*]] = alloca double, align 8 +// CHECK-NEXT: store double [[TMP0]], ptr [[TMP4]], align 8 +// CHECK-NEXT: store double [[TMP1]], ptr [[TMP5]], align 8 +// CHECK-NEXT: store double [[TMP2]], ptr [[TMP6]], align 8 +// CHECK-NEXT: [[TMP7:%.*]] = load double, ptr [[TMP4]], align 8 +// CHECK-NEXT: [[TMP8:%.*]] = load double, ptr [[TMP6]], align 8 +// CHECK-NEXT: [[TMP9:%.*]] = load double, ptr [[TMP5]], align 8 +// CHECK-NEXT: [[TMP10:%.*]] = fmul double [[TMP8]], [[TMP9]] +// CHECK-NEXT: [[TMP11:%.*]] = fadd double [[TMP7]], [[TMP10]] +// CHECK-NEXT: ret double [[TMP11]] +// +// CHECK-NO-EXT-LABEL: define dso_local double @testFma +// CHECK-NO-EXT-SAME: (double noundef [[TMP0:%.*]], double noundef [[TMP1:%.*]], double noundef [[TMP2:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-NO-EXT-NEXT: [[TMP4:%.*]] = alloca double, align 8 +// CHECK-NO-EXT-NEXT: [[TMP5:%.*]] = alloca double, align 8 +// CHECK-NO-EXT-NEXT: [[TMP6:%.*]] = alloca double, align 8 +// CHECK-NO-EXT-NEXT: store double [[TMP0]], ptr [[TMP4]], align 8 +// CHECK-NO-EXT-NEXT: store double [[TMP1]], ptr [[TMP5]], align 8 +// CHECK-NO-EXT-NEXT: store double [[TMP2]], ptr [[TMP6]], align 8 +// CHECK-NO-EXT-NEXT: [[TMP7:%.*]] = load double, ptr [[TMP4]], align 8 +// CHECK-NO-EXT-NEXT: [[TMP8:%.*]] = load double, ptr [[TMP6]], align 8 +// CHECK-NO-EXT-NEXT: [[TMP9:%.*]] = load double, ptr [[TMP5]], align 8 +// CHECK-NO-EXT-NEXT: [[TMP10:%.*]] = call double @llvm.fmuladd.f64(double [[TMP8]], double [[TMP9]], double [[TMP7]]) +// CHECK-NO-EXT-NEXT: ret double [[TMP10]] +// +double testFma(double add, double mul, double num) { + return add + num*mul; +} diff --git a/clang/test/CodeGen/arithmetic-fence-builtin.c b/clang/test/CodeGen/arithmetic-fence-builtin.c --- a/clang/test/CodeGen/arithmetic-fence-builtin.c +++ b/clang/test/CodeGen/arithmetic-fence-builtin.c @@ -1,6 +1,7 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // Test with fast math // RUN: %clang_cc1 -triple i386-pc-linux-gnu -emit-llvm -DFAST \ -// RUN: -mreassociate \ +// RUN: -mreassociate -target-feature +fma \ // RUN: -o - %s | FileCheck --check-prefixes CHECK,CHECKFAST,CHECKNP %s // // RUN: %clang_cc1 -triple aarch64-unknown-linux-gnu -emit-llvm -DFAST \ @@ -8,19 +9,19 @@ // RUN: -o - %s | FileCheck --check-prefixes CHECK,CHECKFAST,CHECKNP %s // // Test with fast math and fprotect-parens -// RUN: %clang_cc1 -triple i386-pc-linux-gnu -emit-llvm -DFAST \ +// RUN: %clang_cc1 -triple i386-pc-linux-gnu -emit-llvm -DFAST -target-feature +fma \ // RUN: -mreassociate -fprotect-parens -ffp-contract=on\ // RUN: -o - %s | FileCheck --check-prefixes CHECK,CHECKFAST,CHECKPP %s // // RUN: %clang_cc1 -triple aarch64-unknown-linux-gnu -emit-llvm -DFAST \ -// RUN: -mreassociate -fprotect-parens -ffp-contract=on\ +// RUN: -mreassociate -fprotect-parens -ffp-contract=on \ // RUN: -o - %s | FileCheck --check-prefixes CHECK,CHECKFAST,CHECKPP %s // // Test without fast math: llvm intrinsic not created -// RUN: %clang_cc1 -triple i386-pc-linux-gnu -emit-llvm -fprotect-parens\ +// RUN: %clang_cc1 -triple i386-pc-linux-gnu -emit-llvm -fprotect-parens -target-feature +fma \ // RUN: -o - %s | FileCheck --implicit-check-not="llvm.arithmetic.fence" %s // -// RUN: %clang_cc1 -triple aarch64-unknown-linux-gnu -emit-llvm -fprotect-parens\ +// RUN: %clang_cc1 -triple aarch64-unknown-linux-gnu -emit-llvm -fprotect-parens \ // RUN: -o - %s | FileCheck --implicit-check-not="llvm.arithmetic.fence" %s // // Test with fast math on spir target @@ -30,37 +31,90 @@ // int v; +// CHECKPP-LABEL: define dso_local i32 @addit +// CHECKPP-SAME: (float noundef [[A:%.*]], float noundef [[B:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECKPP-NEXT: entry: +// CHECKPP-NEXT: [[A_ADDR:%.*]] = alloca float, align 4 +// CHECKPP-NEXT: [[B_ADDR:%.*]] = alloca float, align 4 +// CHECKPP-NEXT: [[CD:%.*]] = alloca { double, double }, align 8 +// CHECKPP-NEXT: [[CD1:%.*]] = alloca { double, double }, align 8 +// CHECKPP-NEXT: [[VEC1:%.*]] = alloca <2 x float>, align 8 +// CHECKPP-NEXT: [[VEC2:%.*]] = alloca <2 x float>, align 8 +// CHECKPP-NEXT: store float [[A]], ptr [[A_ADDR]], align 4 +// CHECKPP-NEXT: store float [[B]], ptr [[B_ADDR]], align 4 +// CHECKPP-NEXT: [[CD1_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[CD1]], i32 0, i32 0 +// CHECKPP-NEXT: [[CD1_REAL:%.*]] = load double, ptr [[CD1_REALP]], align 8 +// CHECKPP-NEXT: [[CD1_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[CD1]], i32 0, i32 1 +// CHECKPP-NEXT: [[CD1_IMAG:%.*]] = load double, ptr [[CD1_IMAGP]], align 8 +// CHECKPP-NEXT: [[TMP0:%.*]] = call reassoc double @llvm.arithmetic.fence.f64(double [[CD1_REAL]]) +// CHECKPP-NEXT: [[TMP1:%.*]] = call reassoc double @llvm.arithmetic.fence.f64(double [[CD1_IMAG]]) +// CHECKPP-NEXT: [[CD_REALP:%.*]] = getelementptr inbounds { double, double }, ptr [[CD]], i32 0, i32 0 +// CHECKPP-NEXT: [[CD_IMAGP:%.*]] = getelementptr inbounds { double, double }, ptr [[CD]], i32 0, i32 1 +// CHECKPP-NEXT: store double [[TMP0]], ptr [[CD_REALP]], align 8 +// CHECKPP-NEXT: store double [[TMP1]], ptr [[CD_IMAGP]], align 8 +// CHECKPP-NEXT: [[TMP2:%.*]] = load <2 x float>, ptr [[VEC2]], align 8 +// CHECKPP-NEXT: [[TMP3:%.*]] = call reassoc <2 x float> @llvm.arithmetic.fence.v2f32(<2 x float> [[TMP2]]) +// CHECKPP-NEXT: store <2 x float> [[TMP3]], ptr [[VEC1]], align 8 +// CHECKPP-NEXT: [[TMP4:%.*]] = load <2 x float>, ptr [[VEC2]], align 8 +// CHECKPP-NEXT: [[TMP5:%.*]] = load <2 x float>, ptr [[VEC1]], align 8 +// CHECKPP-NEXT: [[ADD:%.*]] = fadd reassoc <2 x float> [[TMP4]], [[TMP5]] +// CHECKPP-NEXT: [[TMP6:%.*]] = call reassoc <2 x float> @llvm.arithmetic.fence.v2f32(<2 x float> [[ADD]]) +// CHECKPP-NEXT: store <2 x float> [[TMP6]], ptr [[VEC2]], align 8 +// CHECKPP-NEXT: [[TMP7:%.*]] = load float, ptr [[A_ADDR]], align 4 +// CHECKPP-NEXT: [[TMP8:%.*]] = load float, ptr [[B_ADDR]], align 4 +// CHECKPP-NEXT: [[ADD1:%.*]] = fadd reassoc float [[TMP7]], [[TMP8]] +// CHECKPP-NEXT: [[TMP9:%.*]] = call reassoc float @llvm.arithmetic.fence.f32(float [[ADD1]]) +// CHECKPP-NEXT: [[CONV:%.*]] = fptosi float [[TMP9]] to i32 +// CHECKPP-NEXT: store i32 [[CONV]], ptr @v, align 4 +// CHECKPP-NEXT: [[TMP10:%.*]] = load float, ptr [[A_ADDR]], align 4 +// CHECKPP-NEXT: [[TMP11:%.*]] = load float, ptr [[B_ADDR]], align 4 +// CHECKPP-NEXT: [[ADD2:%.*]] = fadd reassoc float [[TMP10]], [[TMP11]] +// CHECKPP-NEXT: [[TMP12:%.*]] = call reassoc float @llvm.arithmetic.fence.f32(float [[ADD2]]) +// CHECKPP-NEXT: [[CONV3:%.*]] = fptosi float [[TMP12]] to i32 +// CHECKPP-NEXT: store i32 [[CONV3]], ptr @v, align 4 +// CHECKPP-NEXT: [[TMP13:%.*]] = load float, ptr [[A_ADDR]], align 4 +// CHECKPP-NEXT: [[TMP14:%.*]] = load float, ptr [[B_ADDR]], align 4 +// CHECKPP-NEXT: [[TMP15:%.*]] = load float, ptr [[B_ADDR]], align 4 +// CHECKPP-NEXT: [[MUL:%.*]] = fmul reassoc float [[TMP14]], [[TMP15]] +// CHECKPP-NEXT: [[TMP16:%.*]] = call reassoc float @llvm.arithmetic.fence.f32(float [[MUL]]) +// CHECKPP-NEXT: [[ADD4:%.*]] = fadd reassoc float [[TMP13]], [[TMP16]] +// CHECKPP-NEXT: [[CONV5:%.*]] = fptosi float [[ADD4]] to i32 +// CHECKPP-NEXT: store i32 [[CONV5]], ptr @v, align 4 +// CHECKPP-NEXT: [[TMP17:%.*]] = load float, ptr [[B_ADDR]], align 4 +// CHECKPP-NEXT: [[TMP18:%.*]] = load float, ptr [[A_ADDR]], align 4 +// CHECKPP-NEXT: [[TMP19:%.*]] = load float, ptr [[A_ADDR]], align 4 +// CHECKPP-NEXT: [[TMP20:%.*]] = call reassoc float @llvm.fmuladd.f32(float [[TMP18]], float [[TMP19]], float [[TMP17]]) +// CHECKPP-NEXT: [[CONV7:%.*]] = fptosi float [[TMP20]] to i32 +// CHECKPP-NEXT: store i32 [[CONV7]], ptr @v, align 4 +// CHECKPP-NEXT: [[TMP21:%.*]] = load float, ptr [[B_ADDR]], align 4 +// CHECKPP-NEXT: [[TMP22:%.*]] = load float, ptr [[A_ADDR]], align 4 +// CHECKPP-NEXT: [[TMP23:%.*]] = load float, ptr [[A_ADDR]], align 4 +// CHECKPP-NEXT: [[MUL8:%.*]] = fmul reassoc float [[TMP22]], [[TMP23]] +// CHECKPP-NEXT: [[TMP24:%.*]] = call reassoc float @llvm.arithmetic.fence.f32(float [[MUL8]]) +// CHECKPP-NEXT: [[ADD9:%.*]] = fadd reassoc float [[TMP21]], [[TMP24]] +// CHECKPP-NEXT: [[CONV10:%.*]] = fptosi float [[ADD9]] to i32 +// CHECKPP-NEXT: store i32 [[CONV10]], ptr @v, align 4 +// CHECKPP-NEXT: [[TMP25:%.*]] = load float, ptr [[A_ADDR]], align 4 +// CHECKPP-NEXT: store float [[TMP25]], ptr [[B_ADDR]], align 4 +// CHECKPP-NEXT: [[TMP26:%.*]] = load float, ptr [[B_ADDR]], align 4 +// CHECKPP-NEXT: store float [[TMP26]], ptr [[A_ADDR]], align 4 +// CHECKPP-NEXT: ret i32 0 +// int addit(float a, float b) { - // CHECK: define {{.*}}@addit(float noundef %a, float noundef %b) #0 { _Complex double cd, cd1; cd = __arithmetic_fence(cd1); - // CHECKFAST: call{{.*}} double @llvm.arithmetic.fence.f64({{.*}}real) - // CHECKFAST: call{{.*}} double @llvm.arithmetic.fence.f64({{.*}}imag) // Vector should be supported. typedef float __v2f32 __attribute__((__vector_size__(8))); __v2f32 vec1, vec2; vec1 = __arithmetic_fence(vec2); - // CHECKFAST: call{{.*}} <2 x float> @llvm.arithmetic.fence.v2f32 vec2 = (vec2 + vec1); - // CHECKPP: call{{.*}} <2 x float> @llvm.arithmetic.fence.v2f32 v = __arithmetic_fence(a + b); - // CHECKFAST: call{{.*}} float @llvm.arithmetic.fence.f32(float %add{{.*}}) v = (a + b); - // CHECKPP: call{{.*}} float @llvm.arithmetic.fence.f32(float %add{{.*}}) v = a + (b*b); - // CHECKPP: fmul reassoc - // CHECKPP-NEXT: call{{.*}} float @llvm.arithmetic.fence.f32(float %mul) - // CHECKNP: fmul - // CHECKNP: fadd v = b + a*a; - // CHECKPP: call{{.*}} float @llvm.fmuladd.f32 - // CHECKNP: fmul - // CHECKNP: fadd v = b + __arithmetic_fence(a*a); // Fence blocks recognition of FMA - // CHECKPP: fmul - // CHECKNP: fmul b = (a); (a) = b; @@ -73,19 +127,32 @@ return 0; // CHECK-NEXT ret i32 0 } +// CHECKPP-LABEL: define dso_local i32 @addit1 +// CHECKPP-SAME: (i32 noundef [[A:%.*]], i32 noundef [[B:%.*]]) #[[ATTR0]] { +// CHECKPP-NEXT: entry: +// CHECKPP-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 +// CHECKPP-NEXT: [[B_ADDR:%.*]] = alloca i32, align 4 +// CHECKPP-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 +// CHECKPP-NEXT: store i32 [[B]], ptr [[B_ADDR]], align 4 +// CHECKPP-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4 +// CHECKPP-NEXT: [[TMP1:%.*]] = load i32, ptr [[B_ADDR]], align 4 +// CHECKPP-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[TMP1]] +// CHECKPP-NEXT: store i32 [[ADD]], ptr @v, align 4 +// CHECKPP-NEXT: ret i32 0 +// int addit1(int a, int b) { - // CHECK: define {{.*}}@addit1(i32 noundef %a, i32 noundef %b{{.*}} v = (a + b); - // CHECK-NOT: call{{.*}} float @llvm.arithmetic.fence.int(float noundef %add) return 0; } #ifdef FAST #pragma float_control(precise, on) int subit(float a, float b, float *fp) { - // CHECKFAST: define {{.*}}@subit(float noundef %a, float noundef %b{{.*}} *fp = __arithmetic_fence(a - b); *fp = (a + b); - // CHECK-NOT: call{{.*}} float @llvm.arithmetic.fence.f32(float noundef %add) return 0; } #endif +//// NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: +// CHECK: {{.*}} +// CHECKFAST: {{.*}} +// CHECKNP: {{.*}} diff --git a/clang/test/CodeGen/constrained-math-builtins.c b/clang/test/CodeGen/constrained-math-builtins.c --- a/clang/test/CodeGen/constrained-math-builtins.c +++ b/clang/test/CodeGen/constrained-math-builtins.c @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -triple x86_64-linux -ffp-exception-behavior=maytrap -w -S -o - -emit-llvm %s | FileCheck %s +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 +// RUN: %clang_cc1 -triple x86_64-linux -ffp-exception-behavior=maytrap -target-feature +fma -w -S -o - -emit-llvm %s | FileCheck %s // Test codegen of constrained math builtins. // @@ -7,308 +8,505 @@ #pragma float_control(except, on) +// CHECK-LABEL: define dso_local void @foo +// CHECK-SAME: (ptr noundef [[D:%.*]], float noundef [[F:%.*]], ptr noundef [[FP:%.*]], ptr noundef [[L:%.*]], ptr noundef [[I:%.*]], ptr noundef [[C:%.*]], half noundef [[H:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[D_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[F_ADDR:%.*]] = alloca float, align 4 +// CHECK-NEXT: [[FP_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[L_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[I_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[C_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[H_ADDR:%.*]] = alloca half, align 2 +// CHECK-NEXT: store ptr [[D]], ptr [[D_ADDR]], align 8 +// CHECK-NEXT: store float [[F]], ptr [[F_ADDR]], align 4 +// CHECK-NEXT: store ptr [[FP]], ptr [[FP_ADDR]], align 8 +// CHECK-NEXT: store ptr [[L]], ptr [[L_ADDR]], align 8 +// CHECK-NEXT: store ptr [[I]], ptr [[I_ADDR]], align 8 +// CHECK-NEXT: store ptr [[C]], ptr [[C_ADDR]], align 8 +// CHECK-NEXT: store half [[H]], ptr [[H_ADDR]], align 2 +// CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV:%.*]] = call double @llvm.experimental.constrained.fpext.f64.f32(float [[TMP0]], metadata !"fpexcept.strict") #[[ATTR2:[0-9]+]] +// CHECK-NEXT: [[TMP1:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV1:%.*]] = call double @llvm.experimental.constrained.fpext.f64.f32(float [[TMP1]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[FMOD:%.*]] = call double @llvm.experimental.constrained.frem.f64(double [[CONV]], double [[CONV1]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[CONV2:%.*]] = call float @llvm.experimental.constrained.fptrunc.f32.f64(double [[FMOD]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: store float [[CONV2]], ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[TMP2:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[TMP3:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[FMOD3:%.*]] = call float @llvm.experimental.constrained.frem.f32(float [[TMP2]], float [[TMP3]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: store float [[FMOD3]], ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[TMP4:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV4:%.*]] = call x86_fp80 @llvm.experimental.constrained.fpext.f80.f32(float [[TMP4]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP5:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV5:%.*]] = call x86_fp80 @llvm.experimental.constrained.fpext.f80.f32(float [[TMP5]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[FMOD6:%.*]] = call x86_fp80 @llvm.experimental.constrained.frem.f80(x86_fp80 [[CONV4]], x86_fp80 [[CONV5]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[CONV7:%.*]] = call float @llvm.experimental.constrained.fptrunc.f32.f80(x86_fp80 [[FMOD6]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: store float [[CONV7]], ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[TMP6:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV8:%.*]] = call fp128 @llvm.experimental.constrained.fpext.f128.f32(float [[TMP6]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP7:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV9:%.*]] = call fp128 @llvm.experimental.constrained.fpext.f128.f32(float [[TMP7]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[FMOD10:%.*]] = call fp128 @llvm.experimental.constrained.frem.f128(fp128 [[CONV8]], fp128 [[CONV9]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[CONV11:%.*]] = call float @llvm.experimental.constrained.fptrunc.f32.f128(fp128 [[FMOD10]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: store float [[CONV11]], ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[TMP8:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV12:%.*]] = call double @llvm.experimental.constrained.fpext.f64.f32(float [[TMP8]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP9:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV13:%.*]] = call double @llvm.experimental.constrained.fpext.f64.f32(float [[TMP9]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP10:%.*]] = call double @llvm.experimental.constrained.pow.f64(double [[CONV12]], double [[CONV13]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP11:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[TMP12:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[TMP13:%.*]] = call float @llvm.experimental.constrained.pow.f32(float [[TMP11]], float [[TMP12]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP14:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV14:%.*]] = call x86_fp80 @llvm.experimental.constrained.fpext.f80.f32(float [[TMP14]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP15:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV15:%.*]] = call x86_fp80 @llvm.experimental.constrained.fpext.f80.f32(float [[TMP15]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP16:%.*]] = call x86_fp80 @llvm.experimental.constrained.pow.f80(x86_fp80 [[CONV14]], x86_fp80 [[CONV15]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP17:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV16:%.*]] = call fp128 @llvm.experimental.constrained.fpext.f128.f32(float [[TMP17]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP18:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV17:%.*]] = call fp128 @llvm.experimental.constrained.fpext.f128.f32(float [[TMP18]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP19:%.*]] = call fp128 @llvm.experimental.constrained.pow.f128(fp128 [[CONV16]], fp128 [[CONV17]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP20:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV18:%.*]] = call double @llvm.experimental.constrained.fpext.f64.f32(float [[TMP20]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP21:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV19:%.*]] = call i32 @llvm.experimental.constrained.fptosi.i32.f32(float [[TMP21]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP22:%.*]] = call double @llvm.experimental.constrained.powi.f64(double [[CONV18]], i32 [[CONV19]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP23:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[TMP24:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV20:%.*]] = call i32 @llvm.experimental.constrained.fptosi.i32.f32(float [[TMP24]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP25:%.*]] = call float @llvm.experimental.constrained.powi.f32(float [[TMP23]], i32 [[CONV20]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP26:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV21:%.*]] = call x86_fp80 @llvm.experimental.constrained.fpext.f80.f32(float [[TMP26]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP27:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV22:%.*]] = call i32 @llvm.experimental.constrained.fptosi.i32.f32(float [[TMP27]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP28:%.*]] = call x86_fp80 @llvm.experimental.constrained.powi.f80(x86_fp80 [[CONV21]], i32 [[CONV22]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP29:%.*]] = load half, ptr [[H_ADDR]], align 2 +// CHECK-NEXT: [[TMP30:%.*]] = load ptr, ptr [[I_ADDR]], align 8 +// CHECK-NEXT: [[TMP31:%.*]] = load i32, ptr [[TMP30]], align 4 +// CHECK-NEXT: [[TMP32:%.*]] = call half @llvm.experimental.constrained.ldexp.f16.i32(half [[TMP29]], i32 [[TMP31]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: store half [[TMP32]], ptr [[H_ADDR]], align 2 +// CHECK-NEXT: [[TMP33:%.*]] = load ptr, ptr [[D_ADDR]], align 8 +// CHECK-NEXT: [[TMP34:%.*]] = load double, ptr [[TMP33]], align 8 +// CHECK-NEXT: [[TMP35:%.*]] = load ptr, ptr [[I_ADDR]], align 8 +// CHECK-NEXT: [[TMP36:%.*]] = load i32, ptr [[TMP35]], align 4 +// CHECK-NEXT: [[TMP37:%.*]] = call double @llvm.experimental.constrained.ldexp.f64.i32(double [[TMP34]], i32 [[TMP36]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP38:%.*]] = load ptr, ptr [[D_ADDR]], align 8 +// CHECK-NEXT: store double [[TMP37]], ptr [[TMP38]], align 8 +// CHECK-NEXT: [[TMP39:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[TMP40:%.*]] = load ptr, ptr [[I_ADDR]], align 8 +// CHECK-NEXT: [[TMP41:%.*]] = load i32, ptr [[TMP40]], align 4 +// CHECK-NEXT: [[TMP42:%.*]] = call float @llvm.experimental.constrained.ldexp.f32.i32(float [[TMP39]], i32 [[TMP41]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: store float [[TMP42]], ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[TMP43:%.*]] = load ptr, ptr [[L_ADDR]], align 8 +// CHECK-NEXT: [[TMP44:%.*]] = load x86_fp80, ptr [[TMP43]], align 16 +// CHECK-NEXT: [[TMP45:%.*]] = load ptr, ptr [[I_ADDR]], align 8 +// CHECK-NEXT: [[TMP46:%.*]] = load i32, ptr [[TMP45]], align 4 +// CHECK-NEXT: [[TMP47:%.*]] = call x86_fp80 @llvm.experimental.constrained.ldexp.f80.i32(x86_fp80 [[TMP44]], i32 [[TMP46]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP48:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV23:%.*]] = call double @llvm.experimental.constrained.fpext.f64.f32(float [[TMP48]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP49:%.*]] = call double @llvm.experimental.constrained.ceil.f64(double [[CONV23]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP50:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[TMP51:%.*]] = call float @llvm.experimental.constrained.ceil.f32(float [[TMP50]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP52:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV24:%.*]] = call x86_fp80 @llvm.experimental.constrained.fpext.f80.f32(float [[TMP52]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP53:%.*]] = call x86_fp80 @llvm.experimental.constrained.ceil.f80(x86_fp80 [[CONV24]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP54:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV25:%.*]] = call fp128 @llvm.experimental.constrained.fpext.f128.f32(float [[TMP54]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP55:%.*]] = call fp128 @llvm.experimental.constrained.ceil.f128(fp128 [[CONV25]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP56:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV26:%.*]] = call double @llvm.experimental.constrained.fpext.f64.f32(float [[TMP56]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP57:%.*]] = call double @llvm.experimental.constrained.cos.f64(double [[CONV26]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP58:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[TMP59:%.*]] = call float @llvm.experimental.constrained.cos.f32(float [[TMP58]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP60:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV27:%.*]] = call x86_fp80 @llvm.experimental.constrained.fpext.f80.f32(float [[TMP60]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP61:%.*]] = call x86_fp80 @llvm.experimental.constrained.cos.f80(x86_fp80 [[CONV27]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP62:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV28:%.*]] = call fp128 @llvm.experimental.constrained.fpext.f128.f32(float [[TMP62]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP63:%.*]] = call fp128 @llvm.experimental.constrained.cos.f128(fp128 [[CONV28]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP64:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV29:%.*]] = call double @llvm.experimental.constrained.fpext.f64.f32(float [[TMP64]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP65:%.*]] = call double @llvm.experimental.constrained.exp.f64(double [[CONV29]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP66:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[TMP67:%.*]] = call float @llvm.experimental.constrained.exp.f32(float [[TMP66]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP68:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV30:%.*]] = call x86_fp80 @llvm.experimental.constrained.fpext.f80.f32(float [[TMP68]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP69:%.*]] = call x86_fp80 @llvm.experimental.constrained.exp.f80(x86_fp80 [[CONV30]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP70:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV31:%.*]] = call fp128 @llvm.experimental.constrained.fpext.f128.f32(float [[TMP70]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP71:%.*]] = call fp128 @llvm.experimental.constrained.exp.f128(fp128 [[CONV31]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP72:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV32:%.*]] = call double @llvm.experimental.constrained.fpext.f64.f32(float [[TMP72]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP73:%.*]] = call double @llvm.experimental.constrained.exp2.f64(double [[CONV32]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP74:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[TMP75:%.*]] = call float @llvm.experimental.constrained.exp2.f32(float [[TMP74]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP76:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV33:%.*]] = call x86_fp80 @llvm.experimental.constrained.fpext.f80.f32(float [[TMP76]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP77:%.*]] = call x86_fp80 @llvm.experimental.constrained.exp2.f80(x86_fp80 [[CONV33]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP78:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV34:%.*]] = call fp128 @llvm.experimental.constrained.fpext.f128.f32(float [[TMP78]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP79:%.*]] = call fp128 @llvm.experimental.constrained.exp2.f128(fp128 [[CONV34]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP80:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV35:%.*]] = call double @llvm.experimental.constrained.fpext.f64.f32(float [[TMP80]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP81:%.*]] = call double @llvm.experimental.constrained.floor.f64(double [[CONV35]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP82:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[TMP83:%.*]] = call float @llvm.experimental.constrained.floor.f32(float [[TMP82]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP84:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV36:%.*]] = call x86_fp80 @llvm.experimental.constrained.fpext.f80.f32(float [[TMP84]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP85:%.*]] = call x86_fp80 @llvm.experimental.constrained.floor.f80(x86_fp80 [[CONV36]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP86:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV37:%.*]] = call fp128 @llvm.experimental.constrained.fpext.f128.f32(float [[TMP86]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP87:%.*]] = call fp128 @llvm.experimental.constrained.floor.f128(fp128 [[CONV37]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP88:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV38:%.*]] = call double @llvm.experimental.constrained.fpext.f64.f32(float [[TMP88]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP89:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV39:%.*]] = call double @llvm.experimental.constrained.fpext.f64.f32(float [[TMP89]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP90:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV40:%.*]] = call double @llvm.experimental.constrained.fpext.f64.f32(float [[TMP90]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP91:%.*]] = call double @llvm.experimental.constrained.fma.f64(double [[CONV38]], double [[CONV39]], double [[CONV40]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP92:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[TMP93:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[TMP94:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[TMP95:%.*]] = call float @llvm.experimental.constrained.fma.f32(float [[TMP92]], float [[TMP93]], float [[TMP94]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP96:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV41:%.*]] = call x86_fp80 @llvm.experimental.constrained.fpext.f80.f32(float [[TMP96]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP97:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV42:%.*]] = call x86_fp80 @llvm.experimental.constrained.fpext.f80.f32(float [[TMP97]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP98:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV43:%.*]] = call x86_fp80 @llvm.experimental.constrained.fpext.f80.f32(float [[TMP98]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP99:%.*]] = call x86_fp80 @llvm.experimental.constrained.fma.f80(x86_fp80 [[CONV41]], x86_fp80 [[CONV42]], x86_fp80 [[CONV43]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP100:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV44:%.*]] = call fp128 @llvm.experimental.constrained.fpext.f128.f32(float [[TMP100]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP101:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV45:%.*]] = call fp128 @llvm.experimental.constrained.fpext.f128.f32(float [[TMP101]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP102:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV46:%.*]] = call fp128 @llvm.experimental.constrained.fpext.f128.f32(float [[TMP102]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP103:%.*]] = call fp128 @llvm.experimental.constrained.fma.f128(fp128 [[CONV44]], fp128 [[CONV45]], fp128 [[CONV46]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP104:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV47:%.*]] = call double @llvm.experimental.constrained.fpext.f64.f32(float [[TMP104]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP105:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV48:%.*]] = call double @llvm.experimental.constrained.fpext.f64.f32(float [[TMP105]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP106:%.*]] = call double @llvm.experimental.constrained.maxnum.f64(double [[CONV47]], double [[CONV48]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP107:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[TMP108:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[TMP109:%.*]] = call float @llvm.experimental.constrained.maxnum.f32(float [[TMP107]], float [[TMP108]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP110:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV49:%.*]] = call x86_fp80 @llvm.experimental.constrained.fpext.f80.f32(float [[TMP110]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP111:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV50:%.*]] = call x86_fp80 @llvm.experimental.constrained.fpext.f80.f32(float [[TMP111]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP112:%.*]] = call x86_fp80 @llvm.experimental.constrained.maxnum.f80(x86_fp80 [[CONV49]], x86_fp80 [[CONV50]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP113:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV51:%.*]] = call fp128 @llvm.experimental.constrained.fpext.f128.f32(float [[TMP113]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP114:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV52:%.*]] = call fp128 @llvm.experimental.constrained.fpext.f128.f32(float [[TMP114]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP115:%.*]] = call fp128 @llvm.experimental.constrained.maxnum.f128(fp128 [[CONV51]], fp128 [[CONV52]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP116:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV53:%.*]] = call double @llvm.experimental.constrained.fpext.f64.f32(float [[TMP116]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP117:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV54:%.*]] = call double @llvm.experimental.constrained.fpext.f64.f32(float [[TMP117]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP118:%.*]] = call double @llvm.experimental.constrained.minnum.f64(double [[CONV53]], double [[CONV54]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP119:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[TMP120:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[TMP121:%.*]] = call float @llvm.experimental.constrained.minnum.f32(float [[TMP119]], float [[TMP120]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP122:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV55:%.*]] = call x86_fp80 @llvm.experimental.constrained.fpext.f80.f32(float [[TMP122]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP123:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV56:%.*]] = call x86_fp80 @llvm.experimental.constrained.fpext.f80.f32(float [[TMP123]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP124:%.*]] = call x86_fp80 @llvm.experimental.constrained.minnum.f80(x86_fp80 [[CONV55]], x86_fp80 [[CONV56]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP125:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV57:%.*]] = call fp128 @llvm.experimental.constrained.fpext.f128.f32(float [[TMP125]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP126:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV58:%.*]] = call fp128 @llvm.experimental.constrained.fpext.f128.f32(float [[TMP126]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP127:%.*]] = call fp128 @llvm.experimental.constrained.minnum.f128(fp128 [[CONV57]], fp128 [[CONV58]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP128:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV59:%.*]] = call double @llvm.experimental.constrained.fpext.f64.f32(float [[TMP128]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP129:%.*]] = call i64 @llvm.experimental.constrained.llrint.i64.f64(double [[CONV59]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP130:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[TMP131:%.*]] = call i64 @llvm.experimental.constrained.llrint.i64.f32(float [[TMP130]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP132:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV60:%.*]] = call x86_fp80 @llvm.experimental.constrained.fpext.f80.f32(float [[TMP132]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP133:%.*]] = call i64 @llvm.experimental.constrained.llrint.i64.f80(x86_fp80 [[CONV60]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP134:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV61:%.*]] = call fp128 @llvm.experimental.constrained.fpext.f128.f32(float [[TMP134]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP135:%.*]] = call i64 @llvm.experimental.constrained.llrint.i64.f128(fp128 [[CONV61]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP136:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV62:%.*]] = call double @llvm.experimental.constrained.fpext.f64.f32(float [[TMP136]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP137:%.*]] = call i64 @llvm.experimental.constrained.llround.i64.f64(double [[CONV62]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP138:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[TMP139:%.*]] = call i64 @llvm.experimental.constrained.llround.i64.f32(float [[TMP138]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP140:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV63:%.*]] = call x86_fp80 @llvm.experimental.constrained.fpext.f80.f32(float [[TMP140]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP141:%.*]] = call i64 @llvm.experimental.constrained.llround.i64.f80(x86_fp80 [[CONV63]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP142:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV64:%.*]] = call fp128 @llvm.experimental.constrained.fpext.f128.f32(float [[TMP142]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP143:%.*]] = call i64 @llvm.experimental.constrained.llround.i64.f128(fp128 [[CONV64]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP144:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV65:%.*]] = call double @llvm.experimental.constrained.fpext.f64.f32(float [[TMP144]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP145:%.*]] = call double @llvm.experimental.constrained.log.f64(double [[CONV65]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP146:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[TMP147:%.*]] = call float @llvm.experimental.constrained.log.f32(float [[TMP146]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP148:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV66:%.*]] = call x86_fp80 @llvm.experimental.constrained.fpext.f80.f32(float [[TMP148]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP149:%.*]] = call x86_fp80 @llvm.experimental.constrained.log.f80(x86_fp80 [[CONV66]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP150:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV67:%.*]] = call fp128 @llvm.experimental.constrained.fpext.f128.f32(float [[TMP150]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP151:%.*]] = call fp128 @llvm.experimental.constrained.log.f128(fp128 [[CONV67]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP152:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV68:%.*]] = call double @llvm.experimental.constrained.fpext.f64.f32(float [[TMP152]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP153:%.*]] = call double @llvm.experimental.constrained.log10.f64(double [[CONV68]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP154:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[TMP155:%.*]] = call float @llvm.experimental.constrained.log10.f32(float [[TMP154]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP156:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV69:%.*]] = call x86_fp80 @llvm.experimental.constrained.fpext.f80.f32(float [[TMP156]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP157:%.*]] = call x86_fp80 @llvm.experimental.constrained.log10.f80(x86_fp80 [[CONV69]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP158:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV70:%.*]] = call fp128 @llvm.experimental.constrained.fpext.f128.f32(float [[TMP158]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP159:%.*]] = call fp128 @llvm.experimental.constrained.log10.f128(fp128 [[CONV70]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP160:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV71:%.*]] = call double @llvm.experimental.constrained.fpext.f64.f32(float [[TMP160]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP161:%.*]] = call double @llvm.experimental.constrained.log2.f64(double [[CONV71]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP162:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[TMP163:%.*]] = call float @llvm.experimental.constrained.log2.f32(float [[TMP162]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP164:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV72:%.*]] = call x86_fp80 @llvm.experimental.constrained.fpext.f80.f32(float [[TMP164]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP165:%.*]] = call x86_fp80 @llvm.experimental.constrained.log2.f80(x86_fp80 [[CONV72]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP166:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV73:%.*]] = call fp128 @llvm.experimental.constrained.fpext.f128.f32(float [[TMP166]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP167:%.*]] = call fp128 @llvm.experimental.constrained.log2.f128(fp128 [[CONV73]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP168:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV74:%.*]] = call double @llvm.experimental.constrained.fpext.f64.f32(float [[TMP168]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP169:%.*]] = call i64 @llvm.experimental.constrained.lrint.i64.f64(double [[CONV74]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP170:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[TMP171:%.*]] = call i64 @llvm.experimental.constrained.lrint.i64.f32(float [[TMP170]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP172:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV75:%.*]] = call x86_fp80 @llvm.experimental.constrained.fpext.f80.f32(float [[TMP172]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP173:%.*]] = call i64 @llvm.experimental.constrained.lrint.i64.f80(x86_fp80 [[CONV75]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP174:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV76:%.*]] = call fp128 @llvm.experimental.constrained.fpext.f128.f32(float [[TMP174]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP175:%.*]] = call i64 @llvm.experimental.constrained.lrint.i64.f128(fp128 [[CONV76]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP176:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV77:%.*]] = call double @llvm.experimental.constrained.fpext.f64.f32(float [[TMP176]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP177:%.*]] = call i64 @llvm.experimental.constrained.lround.i64.f64(double [[CONV77]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP178:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[TMP179:%.*]] = call i64 @llvm.experimental.constrained.lround.i64.f32(float [[TMP178]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP180:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV78:%.*]] = call x86_fp80 @llvm.experimental.constrained.fpext.f80.f32(float [[TMP180]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP181:%.*]] = call i64 @llvm.experimental.constrained.lround.i64.f80(x86_fp80 [[CONV78]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP182:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV79:%.*]] = call fp128 @llvm.experimental.constrained.fpext.f128.f32(float [[TMP182]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP183:%.*]] = call i64 @llvm.experimental.constrained.lround.i64.f128(fp128 [[CONV79]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP184:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV80:%.*]] = call double @llvm.experimental.constrained.fpext.f64.f32(float [[TMP184]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP185:%.*]] = call double @llvm.experimental.constrained.nearbyint.f64(double [[CONV80]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP186:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[TMP187:%.*]] = call float @llvm.experimental.constrained.nearbyint.f32(float [[TMP186]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP188:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV81:%.*]] = call x86_fp80 @llvm.experimental.constrained.fpext.f80.f32(float [[TMP188]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP189:%.*]] = call x86_fp80 @llvm.experimental.constrained.nearbyint.f80(x86_fp80 [[CONV81]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP190:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV82:%.*]] = call fp128 @llvm.experimental.constrained.fpext.f128.f32(float [[TMP190]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP191:%.*]] = call fp128 @llvm.experimental.constrained.nearbyint.f128(fp128 [[CONV82]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP192:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV83:%.*]] = call double @llvm.experimental.constrained.fpext.f64.f32(float [[TMP192]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP193:%.*]] = call double @llvm.experimental.constrained.rint.f64(double [[CONV83]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP194:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[TMP195:%.*]] = call float @llvm.experimental.constrained.rint.f32(float [[TMP194]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP196:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV84:%.*]] = call x86_fp80 @llvm.experimental.constrained.fpext.f80.f32(float [[TMP196]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP197:%.*]] = call x86_fp80 @llvm.experimental.constrained.rint.f80(x86_fp80 [[CONV84]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP198:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV85:%.*]] = call fp128 @llvm.experimental.constrained.fpext.f128.f32(float [[TMP198]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP199:%.*]] = call fp128 @llvm.experimental.constrained.rint.f128(fp128 [[CONV85]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP200:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV86:%.*]] = call double @llvm.experimental.constrained.fpext.f64.f32(float [[TMP200]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP201:%.*]] = call double @llvm.experimental.constrained.round.f64(double [[CONV86]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP202:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[TMP203:%.*]] = call float @llvm.experimental.constrained.round.f32(float [[TMP202]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP204:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV87:%.*]] = call x86_fp80 @llvm.experimental.constrained.fpext.f80.f32(float [[TMP204]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP205:%.*]] = call x86_fp80 @llvm.experimental.constrained.round.f80(x86_fp80 [[CONV87]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP206:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV88:%.*]] = call fp128 @llvm.experimental.constrained.fpext.f128.f32(float [[TMP206]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP207:%.*]] = call fp128 @llvm.experimental.constrained.round.f128(fp128 [[CONV88]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP208:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV89:%.*]] = call double @llvm.experimental.constrained.fpext.f64.f32(float [[TMP208]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP209:%.*]] = call double @llvm.experimental.constrained.sin.f64(double [[CONV89]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP210:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[TMP211:%.*]] = call float @llvm.experimental.constrained.sin.f32(float [[TMP210]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP212:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV90:%.*]] = call x86_fp80 @llvm.experimental.constrained.fpext.f80.f32(float [[TMP212]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP213:%.*]] = call x86_fp80 @llvm.experimental.constrained.sin.f80(x86_fp80 [[CONV90]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP214:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV91:%.*]] = call fp128 @llvm.experimental.constrained.fpext.f128.f32(float [[TMP214]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP215:%.*]] = call fp128 @llvm.experimental.constrained.sin.f128(fp128 [[CONV91]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP216:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV92:%.*]] = call double @llvm.experimental.constrained.fpext.f64.f32(float [[TMP216]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP217:%.*]] = call double @llvm.experimental.constrained.sqrt.f64(double [[CONV92]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP218:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[TMP219:%.*]] = call float @llvm.experimental.constrained.sqrt.f32(float [[TMP218]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP220:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV93:%.*]] = call x86_fp80 @llvm.experimental.constrained.fpext.f80.f32(float [[TMP220]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP221:%.*]] = call x86_fp80 @llvm.experimental.constrained.sqrt.f80(x86_fp80 [[CONV93]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP222:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV94:%.*]] = call fp128 @llvm.experimental.constrained.fpext.f128.f32(float [[TMP222]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP223:%.*]] = call fp128 @llvm.experimental.constrained.sqrt.f128(fp128 [[CONV94]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP224:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV95:%.*]] = call double @llvm.experimental.constrained.fpext.f64.f32(float [[TMP224]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP225:%.*]] = call double @llvm.experimental.constrained.trunc.f64(double [[CONV95]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP226:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[TMP227:%.*]] = call float @llvm.experimental.constrained.trunc.f32(float [[TMP226]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP228:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV96:%.*]] = call x86_fp80 @llvm.experimental.constrained.fpext.f80.f32(float [[TMP228]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP229:%.*]] = call x86_fp80 @llvm.experimental.constrained.trunc.f80(x86_fp80 [[CONV96]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP230:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV97:%.*]] = call fp128 @llvm.experimental.constrained.fpext.f128.f32(float [[TMP230]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP231:%.*]] = call fp128 @llvm.experimental.constrained.trunc.f128(fp128 [[CONV97]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: ret void +// void foo(double *d, float f, float *fp, long double *l, int *i, const char *c, _Float16 h) { f = __builtin_fmod(f,f); f = __builtin_fmodf(f,f); f = __builtin_fmodl(f,f); f = __builtin_fmodf128(f,f); -// CHECK: call double @llvm.experimental.constrained.frem.f64(double %{{.*}}, double %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call float @llvm.experimental.constrained.frem.f32(float %{{.*}}, float %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call x86_fp80 @llvm.experimental.constrained.frem.f80(x86_fp80 %{{.*}}, x86_fp80 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call fp128 @llvm.experimental.constrained.frem.f128(fp128 %{{.*}}, fp128 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") __builtin_pow(f,f); __builtin_powf(f,f); __builtin_powl(f,f); __builtin_powf128(f,f); -// CHECK: call double @llvm.experimental.constrained.pow.f64(double %{{.*}}, double %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call float @llvm.experimental.constrained.pow.f32(float %{{.*}}, float %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call x86_fp80 @llvm.experimental.constrained.pow.f80(x86_fp80 %{{.*}}, x86_fp80 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call fp128 @llvm.experimental.constrained.pow.f128(fp128 %{{.*}}, fp128 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") __builtin_powi(f,f); __builtin_powif(f,f); __builtin_powil(f,f); -// CHECK: call double @llvm.experimental.constrained.powi.f64(double %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call float @llvm.experimental.constrained.powi.f32(float %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call x86_fp80 @llvm.experimental.constrained.powi.f80(x86_fp80 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") h = __builtin_ldexpf16(h, *i); *d = __builtin_ldexp(*d, *i); f = __builtin_ldexpf(f, *i); __builtin_ldexpl(*l, *i); -// CHECK: call half @llvm.experimental.constrained.ldexp.f16.i32(half %{{.*}}, i32 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call double @llvm.experimental.constrained.ldexp.f64.i32(double %{{.*}}, i32 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call float @llvm.experimental.constrained.ldexp.f32.i32(float %{{.*}}, i32 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call x86_fp80 @llvm.experimental.constrained.ldexp.f80.i32(x86_fp80 %{{.*}}, i32 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") __builtin_ceil(f); __builtin_ceilf(f); __builtin_ceill(f); __builtin_ceilf128(f); -// CHECK: call double @llvm.experimental.constrained.ceil.f64(double %{{.*}}, metadata !"fpexcept.strict") -// CHECK: call float @llvm.experimental.constrained.ceil.f32(float %{{.*}}, metadata !"fpexcept.strict") -// CHECK: call x86_fp80 @llvm.experimental.constrained.ceil.f80(x86_fp80 %{{.*}}, metadata !"fpexcept.strict") -// CHECK: call fp128 @llvm.experimental.constrained.ceil.f128(fp128 %{{.*}}, metadata !"fpexcept.strict") __builtin_cos(f); __builtin_cosf(f); __builtin_cosl(f); __builtin_cosf128(f); -// CHECK: call double @llvm.experimental.constrained.cos.f64(double %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call float @llvm.experimental.constrained.cos.f32(float %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call x86_fp80 @llvm.experimental.constrained.cos.f80(x86_fp80 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call fp128 @llvm.experimental.constrained.cos.f128(fp128 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") __builtin_exp(f); __builtin_expf(f); __builtin_expl(f); __builtin_expf128(f); -// CHECK: call double @llvm.experimental.constrained.exp.f64(double %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call float @llvm.experimental.constrained.exp.f32(float %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call x86_fp80 @llvm.experimental.constrained.exp.f80(x86_fp80 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call fp128 @llvm.experimental.constrained.exp.f128(fp128 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") __builtin_exp2(f); __builtin_exp2f(f); __builtin_exp2l(f); __builtin_exp2f128(f); -// CHECK: call double @llvm.experimental.constrained.exp2.f64(double %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call float @llvm.experimental.constrained.exp2.f32(float %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call x86_fp80 @llvm.experimental.constrained.exp2.f80(x86_fp80 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call fp128 @llvm.experimental.constrained.exp2.f128(fp128 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") __builtin_floor(f); __builtin_floorf(f); __builtin_floorl(f); __builtin_floorf128(f); -// CHECK: call double @llvm.experimental.constrained.floor.f64(double %{{.*}}, metadata !"fpexcept.strict") -// CHECK: call float @llvm.experimental.constrained.floor.f32(float %{{.*}}, metadata !"fpexcept.strict") -// CHECK: call x86_fp80 @llvm.experimental.constrained.floor.f80(x86_fp80 %{{.*}}, metadata !"fpexcept.strict") -// CHECK: call fp128 @llvm.experimental.constrained.floor.f128(fp128 %{{.*}}, metadata !"fpexcept.strict") __builtin_fma(f,f,f); __builtin_fmaf(f,f,f); __builtin_fmal(f,f,f); __builtin_fmaf128(f,f,f); -// CHECK: call double @llvm.experimental.constrained.fma.f64(double %{{.*}}, double %{{.*}}, double %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call float @llvm.experimental.constrained.fma.f32(float %{{.*}}, float %{{.*}}, float %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call x86_fp80 @llvm.experimental.constrained.fma.f80(x86_fp80 %{{.*}}, x86_fp80 %{{.*}}, x86_fp80 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call fp128 @llvm.experimental.constrained.fma.f128(fp128 %{{.*}}, fp128 %{{.*}}, fp128 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") __builtin_fmax(f,f); __builtin_fmaxf(f,f); __builtin_fmaxl(f,f); __builtin_fmaxf128(f,f); -// CHECK: call double @llvm.experimental.constrained.maxnum.f64(double %{{.*}}, double %{{.*}}, metadata !"fpexcept.strict") -// CHECK: call float @llvm.experimental.constrained.maxnum.f32(float %{{.*}}, float %{{.*}}, metadata !"fpexcept.strict") -// CHECK: call x86_fp80 @llvm.experimental.constrained.maxnum.f80(x86_fp80 %{{.*}}, x86_fp80 %{{.*}}, metadata !"fpexcept.strict") -// CHECK: call fp128 @llvm.experimental.constrained.maxnum.f128(fp128 %{{.*}}, fp128 %{{.*}}, metadata !"fpexcept.strict") __builtin_fmin(f,f); __builtin_fminf(f,f); __builtin_fminl(f,f); __builtin_fminf128(f,f); -// CHECK: call double @llvm.experimental.constrained.minnum.f64(double %{{.*}}, double %{{.*}}, metadata !"fpexcept.strict") -// CHECK: call float @llvm.experimental.constrained.minnum.f32(float %{{.*}}, float %{{.*}}, metadata !"fpexcept.strict") -// CHECK: call x86_fp80 @llvm.experimental.constrained.minnum.f80(x86_fp80 %{{.*}}, x86_fp80 %{{.*}}, metadata !"fpexcept.strict") -// CHECK: call fp128 @llvm.experimental.constrained.minnum.f128(fp128 %{{.*}}, fp128 %{{.*}}, metadata !"fpexcept.strict") __builtin_llrint(f); __builtin_llrintf(f); __builtin_llrintl(f); __builtin_llrintf128(f); -// CHECK: call i64 @llvm.experimental.constrained.llrint.i64.f64(double %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call i64 @llvm.experimental.constrained.llrint.i64.f32(float %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call i64 @llvm.experimental.constrained.llrint.i64.f80(x86_fp80 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call i64 @llvm.experimental.constrained.llrint.i64.f128(fp128 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") __builtin_llround(f); __builtin_llroundf(f); __builtin_llroundl(f); __builtin_llroundf128(f); -// CHECK: call i64 @llvm.experimental.constrained.llround.i64.f64(double %{{.*}}, metadata !"fpexcept.strict") -// CHECK: call i64 @llvm.experimental.constrained.llround.i64.f32(float %{{.*}}, metadata !"fpexcept.strict") -// CHECK: call i64 @llvm.experimental.constrained.llround.i64.f80(x86_fp80 %{{.*}}, metadata !"fpexcept.strict") -// CHECK: call i64 @llvm.experimental.constrained.llround.i64.f128(fp128 %{{.*}}, metadata !"fpexcept.strict") __builtin_log(f); __builtin_logf(f); __builtin_logl(f); __builtin_logf128(f); -// CHECK: call double @llvm.experimental.constrained.log.f64(double %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call float @llvm.experimental.constrained.log.f32(float %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call x86_fp80 @llvm.experimental.constrained.log.f80(x86_fp80 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call fp128 @llvm.experimental.constrained.log.f128(fp128 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") __builtin_log10(f); __builtin_log10f(f); __builtin_log10l(f); __builtin_log10f128(f); -// CHECK: call double @llvm.experimental.constrained.log10.f64(double %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call float @llvm.experimental.constrained.log10.f32(float %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call x86_fp80 @llvm.experimental.constrained.log10.f80(x86_fp80 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call fp128 @llvm.experimental.constrained.log10.f128(fp128 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") __builtin_log2(f); __builtin_log2f(f); __builtin_log2l(f); __builtin_log2f128(f); -// CHECK: call double @llvm.experimental.constrained.log2.f64(double %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call float @llvm.experimental.constrained.log2.f32(float %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call x86_fp80 @llvm.experimental.constrained.log2.f80(x86_fp80 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call fp128 @llvm.experimental.constrained.log2.f128(fp128 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") __builtin_lrint(f); __builtin_lrintf(f); __builtin_lrintl(f); __builtin_lrintf128(f); -// CHECK: call i64 @llvm.experimental.constrained.lrint.i64.f64(double %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call i64 @llvm.experimental.constrained.lrint.i64.f32(float %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call i64 @llvm.experimental.constrained.lrint.i64.f80(x86_fp80 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call i64 @llvm.experimental.constrained.lrint.i64.f128(fp128 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") __builtin_lround(f); __builtin_lroundf(f); __builtin_lroundl(f); __builtin_lroundf128(f); -// CHECK: call i64 @llvm.experimental.constrained.lround.i64.f64(double %{{.*}}, metadata !"fpexcept.strict") -// CHECK: call i64 @llvm.experimental.constrained.lround.i64.f32(float %{{.*}}, metadata !"fpexcept.strict") -// CHECK: call i64 @llvm.experimental.constrained.lround.i64.f80(x86_fp80 %{{.*}}, metadata !"fpexcept.strict") -// CHECK: call i64 @llvm.experimental.constrained.lround.i64.f128(fp128 %{{.*}}, metadata !"fpexcept.strict") __builtin_nearbyint(f); __builtin_nearbyintf(f); __builtin_nearbyintl(f); __builtin_nearbyintf128(f); -// CHECK: call double @llvm.experimental.constrained.nearbyint.f64(double %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call float @llvm.experimental.constrained.nearbyint.f32(float %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call x86_fp80 @llvm.experimental.constrained.nearbyint.f80(x86_fp80 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call fp128 @llvm.experimental.constrained.nearbyint.f128(fp128 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") __builtin_rint(f); __builtin_rintf(f); __builtin_rintl(f); __builtin_rintf128(f); -// CHECK: call double @llvm.experimental.constrained.rint.f64(double %{{.*}}, metadata !"fpexcept.strict") -// CHECK: call float @llvm.experimental.constrained.rint.f32(float %{{.*}}, metadata !"fpexcept.strict") -// CHECK: call x86_fp80 @llvm.experimental.constrained.rint.f80(x86_fp80 %{{.*}}, metadata !"fpexcept.strict") -// CHECK: call fp128 @llvm.experimental.constrained.rint.f128(fp128 %{{.*}}, metadata !"fpexcept.strict") __builtin_round(f); __builtin_roundf(f); __builtin_roundl(f); __builtin_roundf128(f); -// CHECK: call double @llvm.experimental.constrained.round.f64(double %{{.*}}, metadata !"fpexcept.strict") -// CHECK: call float @llvm.experimental.constrained.round.f32(float %{{.*}}, metadata !"fpexcept.strict") -// CHECK: call x86_fp80 @llvm.experimental.constrained.round.f80(x86_fp80 %{{.*}}, metadata !"fpexcept.strict") -// CHECK: call fp128 @llvm.experimental.constrained.round.f128(fp128 %{{.*}}, metadata !"fpexcept.strict") __builtin_sin(f); __builtin_sinf(f); __builtin_sinl(f); __builtin_sinf128(f); -// CHECK: call double @llvm.experimental.constrained.sin.f64(double %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call float @llvm.experimental.constrained.sin.f32(float %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call x86_fp80 @llvm.experimental.constrained.sin.f80(x86_fp80 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call fp128 @llvm.experimental.constrained.sin.f128(fp128 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") __builtin_sqrt(f); __builtin_sqrtf(f); __builtin_sqrtl(f); __builtin_sqrtf128(f); -// CHECK: call double @llvm.experimental.constrained.sqrt.f64(double %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call float @llvm.experimental.constrained.sqrt.f32(float %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call x86_fp80 @llvm.experimental.constrained.sqrt.f80(x86_fp80 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") -// CHECK: call fp128 @llvm.experimental.constrained.sqrt.f128(fp128 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") __builtin_trunc(f); __builtin_truncf(f); __builtin_truncl(f); __builtin_truncf128(f); -// CHECK: call double @llvm.experimental.constrained.trunc.f64(double %{{.*}}, metadata !"fpexcept.strict") -// CHECK: call float @llvm.experimental.constrained.trunc.f32(float %{{.*}}, metadata !"fpexcept.strict") -// CHECK: call x86_fp80 @llvm.experimental.constrained.trunc.f80(x86_fp80 %{{.*}}, metadata !"fpexcept.strict") -// CHECK: call fp128 @llvm.experimental.constrained.trunc.f128(fp128 %{{.*}}, metadata !"fpexcept.strict") }; -// CHECK: declare double @llvm.experimental.constrained.frem.f64(double, double, metadata, metadata) -// CHECK: declare float @llvm.experimental.constrained.frem.f32(float, float, metadata, metadata) -// CHECK: declare x86_fp80 @llvm.experimental.constrained.frem.f80(x86_fp80, x86_fp80, metadata, metadata) -// CHECK: declare fp128 @llvm.experimental.constrained.frem.f128(fp128, fp128, metadata, metadata) - -// CHECK: declare double @llvm.experimental.constrained.pow.f64(double, double, metadata, metadata) -// CHECK: declare float @llvm.experimental.constrained.pow.f32(float, float, metadata, metadata) -// CHECK: declare x86_fp80 @llvm.experimental.constrained.pow.f80(x86_fp80, x86_fp80, metadata, metadata) -// CHECK: declare fp128 @llvm.experimental.constrained.pow.f128(fp128, fp128, metadata, metadata) - -// CHECK: declare double @llvm.experimental.constrained.powi.f64(double, i32, metadata, metadata) -// CHECK: declare float @llvm.experimental.constrained.powi.f32(float, i32, metadata, metadata) -// CHECK: declare x86_fp80 @llvm.experimental.constrained.powi.f80(x86_fp80, i32, metadata, metadata) - -// CHECK: declare half @llvm.experimental.constrained.ldexp.f16.i32(half, i32, metadata, metadata) -// CHECK: declare double @llvm.experimental.constrained.ldexp.f64.i32(double, i32, metadata, metadata) -// CHECK: declare float @llvm.experimental.constrained.ldexp.f32.i32(float, i32, metadata, metadata) -// CHECK: declare x86_fp80 @llvm.experimental.constrained.ldexp.f80.i32(x86_fp80, i32, metadata, metadata) - -// CHECK: declare double @llvm.experimental.constrained.ceil.f64(double, metadata) -// CHECK: declare float @llvm.experimental.constrained.ceil.f32(float, metadata) -// CHECK: declare x86_fp80 @llvm.experimental.constrained.ceil.f80(x86_fp80, metadata) -// CHECK: declare fp128 @llvm.experimental.constrained.ceil.f128(fp128, metadata) - -// CHECK: declare double @llvm.experimental.constrained.cos.f64(double, metadata, metadata) -// CHECK: declare float @llvm.experimental.constrained.cos.f32(float, metadata, metadata) -// CHECK: declare x86_fp80 @llvm.experimental.constrained.cos.f80(x86_fp80, metadata, metadata) -// CHECK: declare fp128 @llvm.experimental.constrained.cos.f128(fp128, metadata, metadata) - -// CHECK: declare double @llvm.experimental.constrained.exp.f64(double, metadata, metadata) -// CHECK: declare float @llvm.experimental.constrained.exp.f32(float, metadata, metadata) -// CHECK: declare x86_fp80 @llvm.experimental.constrained.exp.f80(x86_fp80, metadata, metadata) -// CHECK: declare fp128 @llvm.experimental.constrained.exp.f128(fp128, metadata, metadata) - -// CHECK: declare double @llvm.experimental.constrained.exp2.f64(double, metadata, metadata) -// CHECK: declare float @llvm.experimental.constrained.exp2.f32(float, metadata, metadata) -// CHECK: declare x86_fp80 @llvm.experimental.constrained.exp2.f80(x86_fp80, metadata, metadata) -// CHECK: declare fp128 @llvm.experimental.constrained.exp2.f128(fp128, metadata, metadata) - -// CHECK: declare double @llvm.experimental.constrained.floor.f64(double, metadata) -// CHECK: declare float @llvm.experimental.constrained.floor.f32(float, metadata) -// CHECK: declare x86_fp80 @llvm.experimental.constrained.floor.f80(x86_fp80, metadata) -// CHECK: declare fp128 @llvm.experimental.constrained.floor.f128(fp128, metadata) - -// CHECK: declare double @llvm.experimental.constrained.fma.f64(double, double, double, metadata, metadata) -// CHECK: declare float @llvm.experimental.constrained.fma.f32(float, float, float, metadata, metadata) -// CHECK: declare x86_fp80 @llvm.experimental.constrained.fma.f80(x86_fp80, x86_fp80, x86_fp80, metadata, metadata) -// CHECK: declare fp128 @llvm.experimental.constrained.fma.f128(fp128, fp128, fp128, metadata, metadata) - -// CHECK: declare double @llvm.experimental.constrained.maxnum.f64(double, double, metadata) -// CHECK: declare float @llvm.experimental.constrained.maxnum.f32(float, float, metadata) -// CHECK: declare x86_fp80 @llvm.experimental.constrained.maxnum.f80(x86_fp80, x86_fp80, metadata) -// CHECK: declare fp128 @llvm.experimental.constrained.maxnum.f128(fp128, fp128, metadata) - -// CHECK: declare double @llvm.experimental.constrained.minnum.f64(double, double, metadata) -// CHECK: declare float @llvm.experimental.constrained.minnum.f32(float, float, metadata) -// CHECK: declare x86_fp80 @llvm.experimental.constrained.minnum.f80(x86_fp80, x86_fp80, metadata) -// CHECK: declare fp128 @llvm.experimental.constrained.minnum.f128(fp128, fp128, metadata) - -// CHECK: declare i64 @llvm.experimental.constrained.llrint.i64.f64(double, metadata, metadata) -// CHECK: declare i64 @llvm.experimental.constrained.llrint.i64.f32(float, metadata, metadata) -// CHECK: declare i64 @llvm.experimental.constrained.llrint.i64.f80(x86_fp80, metadata, metadata) -// CHECK: declare i64 @llvm.experimental.constrained.llrint.i64.f128(fp128, metadata, metadata) - -// CHECK: declare i64 @llvm.experimental.constrained.llround.i64.f64(double, metadata) -// CHECK: declare i64 @llvm.experimental.constrained.llround.i64.f32(float, metadata) -// CHECK: declare i64 @llvm.experimental.constrained.llround.i64.f80(x86_fp80, metadata) -// CHECK: declare i64 @llvm.experimental.constrained.llround.i64.f128(fp128, metadata) - -// CHECK: declare double @llvm.experimental.constrained.log.f64(double, metadata, metadata) -// CHECK: declare float @llvm.experimental.constrained.log.f32(float, metadata, metadata) -// CHECK: declare x86_fp80 @llvm.experimental.constrained.log.f80(x86_fp80, metadata, metadata) -// CHECK: declare fp128 @llvm.experimental.constrained.log.f128(fp128, metadata, metadata) - -// CHECK: declare double @llvm.experimental.constrained.log10.f64(double, metadata, metadata) -// CHECK: declare float @llvm.experimental.constrained.log10.f32(float, metadata, metadata) -// CHECK: declare x86_fp80 @llvm.experimental.constrained.log10.f80(x86_fp80, metadata, metadata) -// CHECK: declare fp128 @llvm.experimental.constrained.log10.f128(fp128, metadata, metadata) - -// CHECK: declare double @llvm.experimental.constrained.log2.f64(double, metadata, metadata) -// CHECK: declare float @llvm.experimental.constrained.log2.f32(float, metadata, metadata) -// CHECK: declare x86_fp80 @llvm.experimental.constrained.log2.f80(x86_fp80, metadata, metadata) -// CHECK: declare fp128 @llvm.experimental.constrained.log2.f128(fp128, metadata, metadata) - -// CHECK: declare i64 @llvm.experimental.constrained.lrint.i64.f64(double, metadata, metadata) -// CHECK: declare i64 @llvm.experimental.constrained.lrint.i64.f32(float, metadata, metadata) -// CHECK: declare i64 @llvm.experimental.constrained.lrint.i64.f80(x86_fp80, metadata, metadata) -// CHECK: declare i64 @llvm.experimental.constrained.lrint.i64.f128(fp128, metadata, metadata) - -// CHECK: declare i64 @llvm.experimental.constrained.lround.i64.f64(double, metadata) -// CHECK: declare i64 @llvm.experimental.constrained.lround.i64.f32(float, metadata) -// CHECK: declare i64 @llvm.experimental.constrained.lround.i64.f80(x86_fp80, metadata) -// CHECK: declare i64 @llvm.experimental.constrained.lround.i64.f128(fp128, metadata) - -// CHECK: declare double @llvm.experimental.constrained.nearbyint.f64(double, metadata, metadata) -// CHECK: declare float @llvm.experimental.constrained.nearbyint.f32(float, metadata, metadata) -// CHECK: declare x86_fp80 @llvm.experimental.constrained.nearbyint.f80(x86_fp80, metadata, metadata) -// CHECK: declare fp128 @llvm.experimental.constrained.nearbyint.f128(fp128, metadata, metadata) - -// CHECK: declare double @llvm.experimental.constrained.rint.f64(double, metadata, metadata) -// CHECK: declare float @llvm.experimental.constrained.rint.f32(float, metadata, metadata) -// CHECK: declare x86_fp80 @llvm.experimental.constrained.rint.f80(x86_fp80, metadata, metadata) -// CHECK: declare fp128 @llvm.experimental.constrained.rint.f128(fp128, metadata, metadata) - -// CHECK: declare double @llvm.experimental.constrained.round.f64(double, metadata) -// CHECK: declare float @llvm.experimental.constrained.round.f32(float, metadata) -// CHECK: declare x86_fp80 @llvm.experimental.constrained.round.f80(x86_fp80, metadata) -// CHECK: declare fp128 @llvm.experimental.constrained.round.f128(fp128, metadata) - -// CHECK: declare double @llvm.experimental.constrained.sin.f64(double, metadata, metadata) -// CHECK: declare float @llvm.experimental.constrained.sin.f32(float, metadata, metadata) -// CHECK: declare x86_fp80 @llvm.experimental.constrained.sin.f80(x86_fp80, metadata, metadata) -// CHECK: declare fp128 @llvm.experimental.constrained.sin.f128(fp128, metadata, metadata) - -// CHECK: declare double @llvm.experimental.constrained.sqrt.f64(double, metadata, metadata) -// CHECK: declare float @llvm.experimental.constrained.sqrt.f32(float, metadata, metadata) -// CHECK: declare x86_fp80 @llvm.experimental.constrained.sqrt.f80(x86_fp80, metadata, metadata) -// CHECK: declare fp128 @llvm.experimental.constrained.sqrt.f128(fp128, metadata, metadata) - -// CHECK: declare double @llvm.experimental.constrained.trunc.f64(double, metadata) -// CHECK: declare float @llvm.experimental.constrained.trunc.f32(float, metadata) -// CHECK: declare x86_fp80 @llvm.experimental.constrained.trunc.f80(x86_fp80, metadata) -// CHECK: declare fp128 @llvm.experimental.constrained.trunc.f128(fp128, metadata) + + + + + + + + + + + + + + + + + + + + + + + + #pragma STDC FP_CONTRACT ON +// CHECK-LABEL: define dso_local void @bar +// CHECK-SAME: (float noundef [[F:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[F_ADDR:%.*]] = alloca float, align 4 +// CHECK-NEXT: store float [[F]], ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[TMP2:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[TMP3:%.*]] = call float @llvm.experimental.constrained.fmuladd.f32(float [[TMP0]], float [[TMP1]], float [[TMP2]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP4:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV:%.*]] = call double @llvm.experimental.constrained.fpext.f64.f32(float [[TMP4]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP5:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV1:%.*]] = call double @llvm.experimental.constrained.fpext.f64.f32(float [[TMP5]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP6:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV2:%.*]] = call double @llvm.experimental.constrained.fpext.f64.f32(float [[TMP6]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[NEG:%.*]] = fneg double [[CONV2]] +// CHECK-NEXT: [[TMP7:%.*]] = call double @llvm.experimental.constrained.fmuladd.f64(double [[CONV]], double [[CONV1]], double [[NEG]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP8:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[FNEG:%.*]] = fneg float [[TMP8]] +// CHECK-NEXT: [[CONV3:%.*]] = call x86_fp80 @llvm.experimental.constrained.fpext.f80.f32(float [[FNEG]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP9:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV4:%.*]] = call x86_fp80 @llvm.experimental.constrained.fpext.f80.f32(float [[TMP9]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP10:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[CONV5:%.*]] = call x86_fp80 @llvm.experimental.constrained.fpext.f80.f32(float [[TMP10]], metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP11:%.*]] = call x86_fp80 @llvm.experimental.constrained.fmuladd.f80(x86_fp80 [[CONV3]], x86_fp80 [[CONV4]], x86_fp80 [[CONV5]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP12:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[TMP13:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[TMP14:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[NEG7:%.*]] = fneg float [[TMP12]] +// CHECK-NEXT: [[NEG8:%.*]] = fneg float [[TMP14]] +// CHECK-NEXT: [[TMP15:%.*]] = call float @llvm.experimental.constrained.fmuladd.f32(float [[NEG7]], float [[TMP13]], float [[NEG8]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: [[TMP16:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[TMP17:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[TMP18:%.*]] = load float, ptr [[F_ADDR]], align 4 +// CHECK-NEXT: [[NEG10:%.*]] = fneg float [[TMP17]] +// CHECK-NEXT: [[TMP19:%.*]] = call float @llvm.experimental.constrained.fmuladd.f32(float [[NEG10]], float [[TMP18]], float [[TMP16]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-NEXT: ret void +// void bar(float f) { f * f + f; (double)f * f - f; @@ -316,14 +514,4 @@ -(f * f) - f; f + -(f * f); - // CHECK: call float @llvm.experimental.constrained.fmuladd.f32(float %{{.*}}, float %{{.*}}, float %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") - // CHECK: fneg - // CHECK: call double @llvm.experimental.constrained.fmuladd.f64(double %{{.*}}, double %{{.*}}, double %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") - // CHECK: fneg - // CHECK: call x86_fp80 @llvm.experimental.constrained.fmuladd.f80(x86_fp80 %{{.*}}, x86_fp80 %{{.*}}, x86_fp80 %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") - // CHECK: fneg - // CHECK: fneg - // CHECK: call float @llvm.experimental.constrained.fmuladd.f32(float %{{.*}}, float %{{.*}}, float %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") - // CHECK: fneg - // CHECK: call float @llvm.experimental.constrained.fmuladd.f32(float %{{.*}}, float %{{.*}}, float %{{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict") }; diff --git a/clang/test/CodeGen/ffp-contract-option.c b/clang/test/CodeGen/ffp-contract-option.c --- a/clang/test/CodeGen/ffp-contract-option.c +++ b/clang/test/CodeGen/ffp-contract-option.c @@ -1,49 +1,50 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: x86-registered-target -// RUN: %clang_cc1 -triple=x86_64 %s -emit-llvm -o - \ +// RUN: %clang_cc1 -triple=x86_64 %s -emit-llvm -o - -target-feature +fma \ // RUN:| FileCheck --check-prefixes CHECK,CHECK-DEFAULT %s -// RUN: %clang_cc1 -triple=x86_64 -ffp-contract=off %s -emit-llvm -o - \ +// RUN: %clang_cc1 -triple=x86_64 -ffp-contract=off %s -emit-llvm -o - -target-feature +fma \ // RUN:| FileCheck --check-prefixes CHECK,CHECK-DEFAULT %s -// RUN: %clang_cc1 -triple=x86_64 -ffp-contract=on %s -emit-llvm -o - \ +// RUN: %clang_cc1 -triple=x86_64 -ffp-contract=on -target-feature +fma %s -emit-llvm -o - \ // RUN:| FileCheck --check-prefixes CHECK,CHECK-ON %s -// RUN: %clang_cc1 -triple=x86_64 -ffp-contract=fast %s -emit-llvm -o - \ +// RUN: %clang_cc1 -triple=x86_64 -ffp-contract=fast -target-feature +fma %s -emit-llvm -o - \ // RUN:| FileCheck --check-prefixes CHECK,CHECK-CONTRACTFAST %s -// RUN: %clang_cc1 -triple=x86_64 -ffast-math %s -emit-llvm -o - \ +// RUN: %clang_cc1 -triple=x86_64 -ffast-math -target-feature +fma %s -emit-llvm -o - \ // RUN:| FileCheck --check-prefixes CHECK,CHECK-CONTRACTOFF %s -// RUN: %clang_cc1 -triple=x86_64 -ffast-math -ffp-contract=off %s -emit-llvm \ +// RUN: %clang_cc1 -triple=x86_64 -ffast-math -ffp-contract=off %s -emit-llvm -target-feature +fma \ // RUN: -o - | FileCheck --check-prefixes CHECK,CHECK-CONTRACTOFF %s -// RUN: %clang_cc1 -triple=x86_64 -ffast-math -ffp-contract=on %s -emit-llvm \ +// RUN: %clang_cc1 -triple=x86_64 -ffast-math -ffp-contract=on -target-feature +fma %s -emit-llvm \ // RUN: -o - | FileCheck --check-prefixes CHECK,CHECK-ONFAST %s -// RUN: %clang_cc1 -triple=x86_64 -ffast-math -ffp-contract=fast %s -emit-llvm \ +// RUN: %clang_cc1 -triple=x86_64 -ffast-math -ffp-contract=fast -target-feature +fma %s -emit-llvm \ // RUN: -o - | FileCheck --check-prefixes CHECK,CHECK-FASTFAST %s -// RUN: %clang_cc1 -triple=x86_64 -ffp-contract=fast -ffast-math %s \ +// RUN: %clang_cc1 -triple=x86_64 -ffp-contract=fast -ffast-math %s -target-feature +fma \ // RUN: -emit-llvm \ // RUN: -o - | FileCheck --check-prefixes CHECK,CHECK-FASTFAST %s -// RUN: %clang_cc1 -triple=x86_64 -ffp-contract=off -fmath-errno \ +// RUN: %clang_cc1 -triple=x86_64 -ffp-contract=off -fmath-errno -target-feature +fma \ // RUN: -fno-rounding-math %s -emit-llvm -o - \ // RUN: -o - | FileCheck --check-prefixes CHECK,CHECK-NOFAST %s // RUN: %clang -S -emit-llvm -fno-fast-math %s -o - \ // RUN: | FileCheck %s --check-prefixes=CHECK,CHECK-FPC-ON -// RUN: %clang -S -emit-llvm -ffp-contract=fast -fno-fast-math \ +// RUN: %clang -S -emit-llvm -ffp-contract=fast -fno-fast-math -mfma \ // RUN: %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-CONTRACTFAST -// RUN: %clang -S -emit-llvm -ffp-contract=on -fno-fast-math \ +// RUN: %clang -S -emit-llvm -ffp-contract=on -fno-fast-math -mfma \ // RUN: %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-FPC-ON // RUN: %clang -S -emit-llvm -ffp-contract=off -fno-fast-math \ // RUN: %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-FPC-OFF -// RUN: %clang -S -emit-llvm -ffp-model=fast -fno-fast-math \ +// RUN: %clang -S -emit-llvm -ffp-model=fast -fno-fast-math -mfma \ // RUN: %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-FPC-ON // RUN: %clang -S -emit-llvm -ffp-model=precise -fno-fast-math \ @@ -53,68 +54,151 @@ // RUN: -target x86_64 %s -o - | FileCheck %s \ // RUN: --check-prefixes=CHECK,CHECK-FPSC-OFF -// RUN: %clang -S -emit-llvm -ffast-math -fno-fast-math \ +// RUN: %clang -S -emit-llvm -ffast-math -fno-fast-math -mfma \ // RUN: %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-FPC-ON +// CHECK-DEFAULT-LABEL: define dso_local float @mymuladd +// CHECK-DEFAULT-SAME: (float noundef [[X:%.*]], float noundef [[Y:%.*]], float noundef [[Z:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-DEFAULT-NEXT: entry: +// CHECK-DEFAULT-NEXT: [[X_ADDR:%.*]] = alloca float, align 4 +// CHECK-DEFAULT-NEXT: [[Y_ADDR:%.*]] = alloca float, align 4 +// CHECK-DEFAULT-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-DEFAULT-NEXT: store float [[X]], ptr [[X_ADDR]], align 4 +// CHECK-DEFAULT-NEXT: store float [[Y]], ptr [[Y_ADDR]], align 4 +// CHECK-DEFAULT-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-DEFAULT-NEXT: [[TMP0:%.*]] = load float, ptr [[X_ADDR]], align 4 +// CHECK-DEFAULT-NEXT: [[TMP1:%.*]] = load float, ptr [[Y_ADDR]], align 4 +// CHECK-DEFAULT-NEXT: [[MUL:%.*]] = fmul float [[TMP0]], [[TMP1]] +// CHECK-DEFAULT-NEXT: [[TMP2:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-DEFAULT-NEXT: [[ADD:%.*]] = fadd float [[MUL]], [[TMP2]] +// CHECK-DEFAULT-NEXT: ret float [[ADD]] +// +// CHECK-ON-LABEL: define dso_local float @mymuladd +// CHECK-ON-SAME: (float noundef [[X:%.*]], float noundef [[Y:%.*]], float noundef [[Z:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-ON-NEXT: entry: +// CHECK-ON-NEXT: [[X_ADDR:%.*]] = alloca float, align 4 +// CHECK-ON-NEXT: [[Y_ADDR:%.*]] = alloca float, align 4 +// CHECK-ON-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-ON-NEXT: store float [[X]], ptr [[X_ADDR]], align 4 +// CHECK-ON-NEXT: store float [[Y]], ptr [[Y_ADDR]], align 4 +// CHECK-ON-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-ON-NEXT: [[TMP0:%.*]] = load float, ptr [[X_ADDR]], align 4 +// CHECK-ON-NEXT: [[TMP1:%.*]] = load float, ptr [[Y_ADDR]], align 4 +// CHECK-ON-NEXT: [[TMP2:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-ON-NEXT: [[TMP3:%.*]] = call float @llvm.fmuladd.f32(float [[TMP0]], float [[TMP1]], float [[TMP2]]) +// CHECK-ON-NEXT: ret float [[TMP3]] +// +// CHECK-CONTRACTOFF-LABEL: define dso_local nofpclass(nan inf) float @mymuladd +// CHECK-CONTRACTOFF-SAME: (float noundef nofpclass(nan inf) [[X:%.*]], float noundef nofpclass(nan inf) [[Y:%.*]], float noundef nofpclass(nan inf) [[Z:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-CONTRACTOFF-NEXT: entry: +// CHECK-CONTRACTOFF-NEXT: [[X_ADDR:%.*]] = alloca float, align 4 +// CHECK-CONTRACTOFF-NEXT: [[Y_ADDR:%.*]] = alloca float, align 4 +// CHECK-CONTRACTOFF-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-CONTRACTOFF-NEXT: store float [[X]], ptr [[X_ADDR]], align 4 +// CHECK-CONTRACTOFF-NEXT: store float [[Y]], ptr [[Y_ADDR]], align 4 +// CHECK-CONTRACTOFF-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-CONTRACTOFF-NEXT: [[TMP0:%.*]] = load float, ptr [[X_ADDR]], align 4 +// CHECK-CONTRACTOFF-NEXT: [[TMP1:%.*]] = load float, ptr [[Y_ADDR]], align 4 +// CHECK-CONTRACTOFF-NEXT: [[MUL:%.*]] = fmul reassoc nnan ninf nsz arcp afn float [[TMP0]], [[TMP1]] +// CHECK-CONTRACTOFF-NEXT: [[TMP2:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-CONTRACTOFF-NEXT: [[ADD:%.*]] = fadd reassoc nnan ninf nsz arcp afn float [[MUL]], [[TMP2]] +// CHECK-CONTRACTOFF-NEXT: ret float [[ADD]] +// +// CHECK-ONFAST-LABEL: define dso_local nofpclass(nan inf) float @mymuladd +// CHECK-ONFAST-SAME: (float noundef nofpclass(nan inf) [[X:%.*]], float noundef nofpclass(nan inf) [[Y:%.*]], float noundef nofpclass(nan inf) [[Z:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-ONFAST-NEXT: entry: +// CHECK-ONFAST-NEXT: [[X_ADDR:%.*]] = alloca float, align 4 +// CHECK-ONFAST-NEXT: [[Y_ADDR:%.*]] = alloca float, align 4 +// CHECK-ONFAST-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-ONFAST-NEXT: store float [[X]], ptr [[X_ADDR]], align 4 +// CHECK-ONFAST-NEXT: store float [[Y]], ptr [[Y_ADDR]], align 4 +// CHECK-ONFAST-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-ONFAST-NEXT: [[TMP0:%.*]] = load float, ptr [[X_ADDR]], align 4 +// CHECK-ONFAST-NEXT: [[TMP1:%.*]] = load float, ptr [[Y_ADDR]], align 4 +// CHECK-ONFAST-NEXT: [[TMP2:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-ONFAST-NEXT: [[TMP3:%.*]] = call reassoc nnan ninf nsz arcp afn float @llvm.fmuladd.f32(float [[TMP0]], float [[TMP1]], float [[TMP2]]) +// CHECK-ONFAST-NEXT: ret float [[TMP3]] +// +// CHECK-FASTFAST-LABEL: define dso_local nofpclass(nan inf) float @mymuladd +// CHECK-FASTFAST-SAME: (float noundef nofpclass(nan inf) [[X:%.*]], float noundef nofpclass(nan inf) [[Y:%.*]], float noundef nofpclass(nan inf) [[Z:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-FASTFAST-NEXT: entry: +// CHECK-FASTFAST-NEXT: [[X_ADDR:%.*]] = alloca float, align 4 +// CHECK-FASTFAST-NEXT: [[Y_ADDR:%.*]] = alloca float, align 4 +// CHECK-FASTFAST-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-FASTFAST-NEXT: store float [[X]], ptr [[X_ADDR]], align 4 +// CHECK-FASTFAST-NEXT: store float [[Y]], ptr [[Y_ADDR]], align 4 +// CHECK-FASTFAST-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-FASTFAST-NEXT: [[TMP0:%.*]] = load float, ptr [[X_ADDR]], align 4 +// CHECK-FASTFAST-NEXT: [[TMP1:%.*]] = load float, ptr [[Y_ADDR]], align 4 +// CHECK-FASTFAST-NEXT: [[MUL:%.*]] = fmul fast float [[TMP0]], [[TMP1]] +// CHECK-FASTFAST-NEXT: [[TMP2:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-FASTFAST-NEXT: [[ADD:%.*]] = fadd fast float [[MUL]], [[TMP2]] +// CHECK-FASTFAST-NEXT: ret float [[ADD]] +// +// CHECK-NOFAST-LABEL: define dso_local float @mymuladd +// CHECK-NOFAST-SAME: (float noundef [[X:%.*]], float noundef [[Y:%.*]], float noundef [[Z:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-NOFAST-NEXT: entry: +// CHECK-NOFAST-NEXT: [[X_ADDR:%.*]] = alloca float, align 4 +// CHECK-NOFAST-NEXT: [[Y_ADDR:%.*]] = alloca float, align 4 +// CHECK-NOFAST-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-NOFAST-NEXT: store float [[X]], ptr [[X_ADDR]], align 4 +// CHECK-NOFAST-NEXT: store float [[Y]], ptr [[Y_ADDR]], align 4 +// CHECK-NOFAST-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-NOFAST-NEXT: [[TMP0:%.*]] = load float, ptr [[X_ADDR]], align 4 +// CHECK-NOFAST-NEXT: [[TMP1:%.*]] = load float, ptr [[Y_ADDR]], align 4 +// CHECK-NOFAST-NEXT: [[MUL:%.*]] = fmul float [[TMP0]], [[TMP1]] +// CHECK-NOFAST-NEXT: [[TMP2:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-NOFAST-NEXT: [[ADD:%.*]] = fadd float [[MUL]], [[TMP2]] +// CHECK-NOFAST-NEXT: ret float [[ADD]] +// +// CHECK-FPC-OFF-LABEL: define dso_local float @mymuladd +// CHECK-FPC-OFF-SAME: (float noundef [[TMP0:%.*]], float noundef [[TMP1:%.*]], float noundef [[TMP2:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-FPC-OFF-NEXT: [[TMP4:%.*]] = alloca float, align 4 +// CHECK-FPC-OFF-NEXT: [[TMP5:%.*]] = alloca float, align 4 +// CHECK-FPC-OFF-NEXT: [[TMP6:%.*]] = alloca float, align 4 +// CHECK-FPC-OFF-NEXT: store float [[TMP0]], ptr [[TMP4]], align 4 +// CHECK-FPC-OFF-NEXT: store float [[TMP1]], ptr [[TMP5]], align 4 +// CHECK-FPC-OFF-NEXT: store float [[TMP2]], ptr [[TMP6]], align 4 +// CHECK-FPC-OFF-NEXT: [[TMP7:%.*]] = load float, ptr [[TMP4]], align 4 +// CHECK-FPC-OFF-NEXT: [[TMP8:%.*]] = load float, ptr [[TMP5]], align 4 +// CHECK-FPC-OFF-NEXT: [[TMP9:%.*]] = fmul float [[TMP7]], [[TMP8]] +// CHECK-FPC-OFF-NEXT: [[TMP10:%.*]] = load float, ptr [[TMP6]], align 4 +// CHECK-FPC-OFF-NEXT: [[TMP11:%.*]] = fadd float [[TMP9]], [[TMP10]] +// CHECK-FPC-OFF-NEXT: ret float [[TMP11]] +// +// CHECK-FPSC-OFF-LABEL: define dso_local float @mymuladd +// CHECK-FPSC-OFF-SAME: (float noundef [[TMP0:%.*]], float noundef [[TMP1:%.*]], float noundef [[TMP2:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-FPSC-OFF-NEXT: [[TMP4:%.*]] = alloca float, align 4 +// CHECK-FPSC-OFF-NEXT: [[TMP5:%.*]] = alloca float, align 4 +// CHECK-FPSC-OFF-NEXT: [[TMP6:%.*]] = alloca float, align 4 +// CHECK-FPSC-OFF-NEXT: store float [[TMP0]], ptr [[TMP4]], align 4 +// CHECK-FPSC-OFF-NEXT: store float [[TMP1]], ptr [[TMP5]], align 4 +// CHECK-FPSC-OFF-NEXT: store float [[TMP2]], ptr [[TMP6]], align 4 +// CHECK-FPSC-OFF-NEXT: [[TMP7:%.*]] = load float, ptr [[TMP4]], align 4 +// CHECK-FPSC-OFF-NEXT: [[TMP8:%.*]] = load float, ptr [[TMP5]], align 4 +// CHECK-FPSC-OFF-NEXT: [[TMP9:%.*]] = call float @llvm.experimental.constrained.fmul.f32(float [[TMP7]], float [[TMP8]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR2:[0-9]+]] +// CHECK-FPSC-OFF-NEXT: [[TMP10:%.*]] = load float, ptr [[TMP6]], align 4 +// CHECK-FPSC-OFF-NEXT: [[TMP11:%.*]] = call float @llvm.experimental.constrained.fadd.f32(float [[TMP9]], float [[TMP10]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-FPSC-OFF-NEXT: ret float [[TMP11]] +// float mymuladd(float x, float y, float z) { - // CHECK: define{{.*}} float @mymuladd return x * y + z; // expected-warning{{overriding '-ffp-contract=fast' option with '-ffp-contract=on'}} - // CHECK-DEFAULT: load float, ptr - // CHECK-DEFAULT: fmul float - // CHECK-DEFAULT: load float, ptr - // CHECK-DEFAULT: fadd float - - // CHECK-ON: load float, ptr - // CHECK-ON: load float, ptr - // CHECK-ON: load float, ptr - // CHECK-ON: call float @llvm.fmuladd.f32(float {{.*}}, float {{.*}}, float {{.*}}) - - // CHECK-CONTRACTFAST: load float, ptr - // CHECK-CONTRACTFAST: load float, ptr - // CHECK-CONTRACTFAST: fmul contract float - // CHECK-CONTRACTFAST: load float, ptr - // CHECK-CONTRACTFAST: fadd contract float - - // CHECK-CONTRACTOFF: load float, ptr - // CHECK-CONTRACTOFF: load float, ptr - // CHECK-CONTRACTOFF: fmul reassoc nnan ninf nsz arcp afn float - // CHECK-CONTRACTOFF: load float, ptr - // CHECK-CONTRACTOFF: fadd reassoc nnan ninf nsz arcp afn float {{.*}}, {{.*}} - - // CHECK-ONFAST: load float, ptr - // CHECK-ONFAST: load float, ptr - // CHECK-ONFAST: load float, ptr - // CHECK-ONFAST: call reassoc nnan ninf nsz arcp afn float @llvm.fmuladd.f32(float {{.*}}, float {{.*}}, float {{.*}}) - - // CHECK-FASTFAST: load float, ptr - // CHECK-FASTFAST: load float, ptr - // CHECK-FASTFAST: fmul fast float - // CHECK-FASTFAST: load float, ptr - // CHECK-FASTFAST: fadd fast float {{.*}}, {{.*}} - - // CHECK-NOFAST: load float, ptr - // CHECK-NOFAST: load float, ptr - // CHECK-NOFAST: fmul float {{.*}}, {{.*}} - // CHECK-NOFAST: load float, ptr - // CHECK-NOFAST: fadd float {{.*}}, {{.*}} - - // CHECK-FPC-ON: load float, ptr - // CHECK-FPC-ON: load float, ptr - // CHECK-FPC-ON: load float, ptr - // CHECK-FPC-ON: call float @llvm.fmuladd.f32(float {{.*}}, float {{.*}}, float {{.*}}) - - // CHECK-FPC-OFF: load float, ptr - // CHECK-FPC-OFF: load float, ptr - // CHECK-FPC-OFF: fmul float - // CHECK-FPC-OFF: load float, ptr - // CHECK-FPC-OFF: fadd float {{.*}}, {{.*}} + + + + + + + + // CHECK-FFPC-OFF: load float, ptr // CHECK-FFPC-OFF: load float, ptr - // CHECK-FPSC-OFF: call float @llvm.experimental.constrained.fmul.f32(float {{.*}}, float {{.*}}, {{.*}}) - // CHECK-FPSC-OFF: load float, ptr - // CHECK-FPSC-OFF: [[RES:%.*]] = call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, {{.*}}) } +//// NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: +// CHECK: {{.*}} +// CHECK-CONTRACTFAST: {{.*}} +// CHECK-FPC-ON: {{.*}} diff --git a/clang/test/CodeGen/ffp-model.c b/clang/test/CodeGen/ffp-model.c --- a/clang/test/CodeGen/ffp-model.c +++ b/clang/test/CodeGen/ffp-model.c @@ -1,8 +1,9 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // REQUIRES: x86-registered-target -// RUN: %clang -S -emit-llvm -ffp-model=fast -emit-llvm %s -o - \ +// RUN: %clang -S -emit-llvm -ffp-model=fast -emit-llvm -mfma %s -o - \ // RUN: | FileCheck %s --check-prefixes=CHECK,CHECK-FAST -// RUN: %clang -S -emit-llvm -ffp-model=precise %s -o - \ +// RUN: %clang -S -emit-llvm -ffp-model=precise %s -o - -mfma \ // RUN: | FileCheck %s --check-prefixes=CHECK,CHECK-PRECISE // RUN: %clang -S -emit-llvm -ffp-model=strict %s -o - \ @@ -12,37 +13,90 @@ // RUN: -target x86_64 %s -o - | FileCheck %s \ // RUN: --check-prefixes CHECK,CHECK-STRICT-FAST -// RUN: %clang -S -emit-llvm -ffp-model=precise -ffast-math \ +// RUN: %clang -S -emit-llvm -ffp-model=precise -ffast-math -mfma \ // RUN: %s -o - | FileCheck %s --check-prefixes CHECK,CHECK-FAST1 +// CHECK-FAST-LABEL: define dso_local nofpclass(nan inf) float @mymuladd +// CHECK-FAST-SAME: (float noundef nofpclass(nan inf) [[TMP0:%.*]], float noundef nofpclass(nan inf) [[TMP1:%.*]], float noundef nofpclass(nan inf) [[TMP2:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-FAST-NEXT: [[TMP4:%.*]] = alloca float, align 4 +// CHECK-FAST-NEXT: [[TMP5:%.*]] = alloca float, align 4 +// CHECK-FAST-NEXT: [[TMP6:%.*]] = alloca float, align 4 +// CHECK-FAST-NEXT: store float [[TMP0]], ptr [[TMP4]], align 4 +// CHECK-FAST-NEXT: store float [[TMP1]], ptr [[TMP5]], align 4 +// CHECK-FAST-NEXT: store float [[TMP2]], ptr [[TMP6]], align 4 +// CHECK-FAST-NEXT: [[TMP7:%.*]] = load float, ptr [[TMP4]], align 4 +// CHECK-FAST-NEXT: [[TMP8:%.*]] = load float, ptr [[TMP5]], align 4 +// CHECK-FAST-NEXT: [[TMP9:%.*]] = fmul fast float [[TMP7]], [[TMP8]] +// CHECK-FAST-NEXT: [[TMP10:%.*]] = load float, ptr [[TMP6]], align 4 +// CHECK-FAST-NEXT: [[TMP11:%.*]] = fadd fast float [[TMP9]], [[TMP10]] +// CHECK-FAST-NEXT: ret float [[TMP11]] +// +// CHECK-PRECISE-LABEL: define dso_local float @mymuladd +// CHECK-PRECISE-SAME: (float noundef [[TMP0:%.*]], float noundef [[TMP1:%.*]], float noundef [[TMP2:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-PRECISE-NEXT: [[TMP4:%.*]] = alloca float, align 4 +// CHECK-PRECISE-NEXT: [[TMP5:%.*]] = alloca float, align 4 +// CHECK-PRECISE-NEXT: [[TMP6:%.*]] = alloca float, align 4 +// CHECK-PRECISE-NEXT: store float [[TMP0]], ptr [[TMP4]], align 4 +// CHECK-PRECISE-NEXT: store float [[TMP1]], ptr [[TMP5]], align 4 +// CHECK-PRECISE-NEXT: store float [[TMP2]], ptr [[TMP6]], align 4 +// CHECK-PRECISE-NEXT: [[TMP7:%.*]] = load float, ptr [[TMP4]], align 4 +// CHECK-PRECISE-NEXT: [[TMP8:%.*]] = load float, ptr [[TMP5]], align 4 +// CHECK-PRECISE-NEXT: [[TMP9:%.*]] = load float, ptr [[TMP6]], align 4 +// CHECK-PRECISE-NEXT: [[TMP10:%.*]] = call float @llvm.fmuladd.f32(float [[TMP7]], float [[TMP8]], float [[TMP9]]) +// CHECK-PRECISE-NEXT: ret float [[TMP10]] +// +// CHECK-STRICT-LABEL: define dso_local float @mymuladd +// CHECK-STRICT-SAME: (float noundef [[TMP0:%.*]], float noundef [[TMP1:%.*]], float noundef [[TMP2:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-STRICT-NEXT: [[TMP4:%.*]] = alloca float, align 4 +// CHECK-STRICT-NEXT: [[TMP5:%.*]] = alloca float, align 4 +// CHECK-STRICT-NEXT: [[TMP6:%.*]] = alloca float, align 4 +// CHECK-STRICT-NEXT: store float [[TMP0]], ptr [[TMP4]], align 4 +// CHECK-STRICT-NEXT: store float [[TMP1]], ptr [[TMP5]], align 4 +// CHECK-STRICT-NEXT: store float [[TMP2]], ptr [[TMP6]], align 4 +// CHECK-STRICT-NEXT: [[TMP7:%.*]] = load float, ptr [[TMP4]], align 4 +// CHECK-STRICT-NEXT: [[TMP8:%.*]] = load float, ptr [[TMP5]], align 4 +// CHECK-STRICT-NEXT: [[TMP9:%.*]] = call float @llvm.experimental.constrained.fmul.f32(float [[TMP7]], float [[TMP8]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR2:[0-9]+]] +// CHECK-STRICT-NEXT: [[TMP10:%.*]] = load float, ptr [[TMP6]], align 4 +// CHECK-STRICT-NEXT: [[TMP11:%.*]] = call float @llvm.experimental.constrained.fadd.f32(float [[TMP9]], float [[TMP10]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-STRICT-NEXT: ret float [[TMP11]] +// +// CHECK-STRICT-FAST-LABEL: define dso_local nofpclass(nan inf) float @mymuladd +// CHECK-STRICT-FAST-SAME: (float noundef nofpclass(nan inf) [[TMP0:%.*]], float noundef nofpclass(nan inf) [[TMP1:%.*]], float noundef nofpclass(nan inf) [[TMP2:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-STRICT-FAST-NEXT: [[TMP4:%.*]] = alloca float, align 4 +// CHECK-STRICT-FAST-NEXT: [[TMP5:%.*]] = alloca float, align 4 +// CHECK-STRICT-FAST-NEXT: [[TMP6:%.*]] = alloca float, align 4 +// CHECK-STRICT-FAST-NEXT: store float [[TMP0]], ptr [[TMP4]], align 4 +// CHECK-STRICT-FAST-NEXT: store float [[TMP1]], ptr [[TMP5]], align 4 +// CHECK-STRICT-FAST-NEXT: store float [[TMP2]], ptr [[TMP6]], align 4 +// CHECK-STRICT-FAST-NEXT: [[TMP7:%.*]] = load float, ptr [[TMP4]], align 4 +// CHECK-STRICT-FAST-NEXT: [[TMP8:%.*]] = load float, ptr [[TMP5]], align 4 +// CHECK-STRICT-FAST-NEXT: [[TMP9:%.*]] = fmul fast float [[TMP7]], [[TMP8]] +// CHECK-STRICT-FAST-NEXT: [[TMP10:%.*]] = load float, ptr [[TMP6]], align 4 +// CHECK-STRICT-FAST-NEXT: [[TMP11:%.*]] = fadd fast float [[TMP9]], [[TMP10]] +// CHECK-STRICT-FAST-NEXT: ret float [[TMP11]] +// +// CHECK-FAST1-LABEL: define dso_local nofpclass(nan inf) float @mymuladd +// CHECK-FAST1-SAME: (float noundef nofpclass(nan inf) [[TMP0:%.*]], float noundef nofpclass(nan inf) [[TMP1:%.*]], float noundef nofpclass(nan inf) [[TMP2:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-FAST1-NEXT: [[TMP4:%.*]] = alloca float, align 4 +// CHECK-FAST1-NEXT: [[TMP5:%.*]] = alloca float, align 4 +// CHECK-FAST1-NEXT: [[TMP6:%.*]] = alloca float, align 4 +// CHECK-FAST1-NEXT: store float [[TMP0]], ptr [[TMP4]], align 4 +// CHECK-FAST1-NEXT: store float [[TMP1]], ptr [[TMP5]], align 4 +// CHECK-FAST1-NEXT: store float [[TMP2]], ptr [[TMP6]], align 4 +// CHECK-FAST1-NEXT: [[TMP7:%.*]] = load float, ptr [[TMP4]], align 4 +// CHECK-FAST1-NEXT: [[TMP8:%.*]] = load float, ptr [[TMP5]], align 4 +// CHECK-FAST1-NEXT: [[TMP9:%.*]] = fmul fast float [[TMP7]], [[TMP8]] +// CHECK-FAST1-NEXT: [[TMP10:%.*]] = load float, ptr [[TMP6]], align 4 +// CHECK-FAST1-NEXT: [[TMP11:%.*]] = fadd fast float [[TMP9]], [[TMP10]] +// CHECK-FAST1-NEXT: ret float [[TMP11]] +// float mymuladd(float x, float y, float z) { - // CHECK: define{{.*}} float @mymuladd return x * y + z; - // CHECK-FAST: fmul fast float - // CHECK-FAST: load float, ptr - // CHECK-FAST: fadd fast float - - // CHECK-PRECISE: load float, ptr - // CHECK-PRECISE: load float, ptr - // CHECK-PRECISE: load float, ptr - // CHECK-PRECISE: call float @llvm.fmuladd.f32(float {{.*}}, float {{.*}}, float {{.*}}) - - // CHECK-STRICT: load float, ptr - // CHECK-STRICT: load float, ptr - // CHECK-STRICT: call float @llvm.experimental.constrained.fmul.f32(float {{.*}}, float {{.*}}, {{.*}}) - // CHECK-STRICT: load float, ptr - // CHECK-STRICT: call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, {{.*}}) - - // CHECK-STRICT-FAST: load float, ptr - // CHECK-STRICT-FAST: load float, ptr - // CHECK-STRICT-FAST: fmul fast float {{.*}}, {{.*}} - // CHECK-STRICT-FAST: load float, ptr - // CHECK-STRICT-FAST: fadd fast float {{.*}}, {{.*}} - - // CHECK-FAST1: load float, ptr - // CHECK-FAST1: load float, ptr - // CHECK-FAST1: fmul fast float {{.*}}, {{.*}} - // CHECK-FAST1: load float, ptr {{.*}} - // CHECK-FAST1: fadd fast float {{.*}}, {{.*}} + + + + } +//// NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: +// CHECK: {{.*}} diff --git a/clang/test/CodeGen/fp-contract-on-asm.c b/clang/test/CodeGen/fp-contract-on-asm.c --- a/clang/test/CodeGen/fp-contract-on-asm.c +++ b/clang/test/CodeGen/fp-contract-on-asm.c @@ -1,18 +1,16 @@ -// RUN: %clang_cc1 -O3 -triple=aarch64-apple-ios -S -o - %s | FileCheck %s +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 +// RUN: %clang_cc1 -O3 -triple=aarch64-apple-ios -emit-llvm -S %s -o - | FileCheck %s // REQUIRES: aarch64-registered-target float fma_test1(float a, float b, float c) { #pragma STDC FP_CONTRACT ON -// CHECK-LABEL: fma_test1: -// CHECK: fmadd float x = a * b + c; return x; } float fma_test2(float a, float b, float c) { -// CHECK-LABEL: fma_test2: -// CHECK: fmul -// CHECK: fadd float x = a * b + c; return x; } +//// NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: +// CHECK: {{.*}} diff --git a/clang/test/CodeGen/fp-contract-pragma.cpp b/clang/test/CodeGen/fp-contract-pragma.cpp --- a/clang/test/CodeGen/fp-contract-pragma.cpp +++ b/clang/test/CodeGen/fp-contract-pragma.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -O3 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -O3 -triple %itanium_abi_triple -emit-llvm -target-feature +fma -o - %s | FileCheck %s // Is FP_CONTRACT honored in a simple case? float fp_contract_1(float a, float b, float c) { diff --git a/clang/test/CodeGen/fp-floatcontrol-stack.cpp b/clang/test/CodeGen/fp-floatcontrol-stack.cpp --- a/clang/test/CodeGen/fp-floatcontrol-stack.cpp +++ b/clang/test/CodeGen/fp-floatcontrol-stack.cpp @@ -1,30 +1,64 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // RUN: %clang_cc1 -triple x86_64-linux-gnu -ffp-contract=on -DDEFAULT=1 -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-DDEFAULT %s // RUN: %clang_cc1 -triple x86_64-linux-gnu -ffp-contract=on -DEBSTRICT=1 -ffp-exception-behavior=strict -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-DEBSTRICT %s // RUN: %clang_cc1 -triple x86_64-linux-gnu -DFAST=1 -ffast-math -ffp-contract=fast -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-FAST %s -// RUN: %clang_cc1 -triple x86_64-linux-gnu -ffp-contract=on -DNOHONOR=1 -menable-no-infs -menable-no-nans -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-NOHONOR %s +// RUN: %clang_cc1 -triple x86_64-linux-gnu -ffp-contract=on -DNOHONOR=1 -menable-no-infs -menable-no-nans -target-feature +fma -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-NOHONOR %s #define FUN(n) \ (float z) { return n * z + n; } -// CHECK-DDEFAULT: Function Attrs: mustprogress noinline nounwind optnone{{$$}} -// CHECK-DEBSTRICT: Function Attrs: mustprogress noinline nounwind optnone strictfp{{$$}} -// CHECK-FAST: Function Attrs: mustprogress noinline nounwind optnone{{$$}} -// CHECK-NOHONOR: Function Attrs: mustprogress noinline nounwind optnone{{$$}} +// CHECK-DDEFAULT-LABEL: define dso_local noundef float @_Z11fun_defaultf +// CHECK-DDEFAULT-SAME: (float noundef [[Z:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-DDEFAULT-NEXT: entry: +// CHECK-DDEFAULT-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-DDEFAULT-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-DDEFAULT-NEXT: [[TMP0:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-DDEFAULT-NEXT: [[MUL:%.*]] = fmul float 1.000000e+00, [[TMP0]] +// CHECK-DDEFAULT-NEXT: [[ADD:%.*]] = fadd float [[MUL]], 1.000000e+00 +// CHECK-DDEFAULT-NEXT: ret float [[ADD]] +// +// CHECK-DEBSTRICT-LABEL: define dso_local noundef float @_Z11fun_defaultf +// CHECK-DEBSTRICT-SAME: (float noundef [[Z:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-DEBSTRICT-NEXT: entry: +// CHECK-DEBSTRICT-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-DEBSTRICT-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-DEBSTRICT-NEXT: [[CONV:%.*]] = call float @llvm.experimental.constrained.sitofp.f32.i32(i32 1, metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR9:[0-9]+]] +// CHECK-DEBSTRICT-NEXT: [[TMP0:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-DEBSTRICT-NEXT: [[MUL:%.*]] = call float @llvm.experimental.constrained.fmul.f32(float [[CONV]], float [[TMP0]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR9]] +// CHECK-DEBSTRICT-NEXT: [[CONV1:%.*]] = call float @llvm.experimental.constrained.sitofp.f32.i32(i32 1, metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR9]] +// CHECK-DEBSTRICT-NEXT: [[ADD:%.*]] = call float @llvm.experimental.constrained.fadd.f32(float [[MUL]], float [[CONV1]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR9]] +// CHECK-DEBSTRICT-NEXT: ret float [[ADD]] +// +// CHECK-FAST-LABEL: define dso_local noundef nofpclass(nan inf) float @_Z11fun_defaultf +// CHECK-FAST-SAME: (float noundef nofpclass(nan inf) [[Z:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-FAST-NEXT: entry: +// CHECK-FAST-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-FAST-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-FAST-NEXT: [[TMP0:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-FAST-NEXT: [[MUL:%.*]] = fmul fast float 1.000000e+00, [[TMP0]] +// CHECK-FAST-NEXT: [[ADD:%.*]] = fadd fast float [[MUL]], 1.000000e+00 +// CHECK-FAST-NEXT: ret float [[ADD]] +// +// CHECK-NOHONOR-LABEL: define dso_local noundef nofpclass(nan inf) float @_Z11fun_defaultf +// CHECK-NOHONOR-SAME: (float noundef nofpclass(nan inf) [[Z:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-NOHONOR-NEXT: entry: +// CHECK-NOHONOR-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-NOHONOR-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-NOHONOR-NEXT: [[TMP0:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-NOHONOR-NEXT: [[TMP1:%.*]] = call nnan ninf float @llvm.fmuladd.f32(float 1.000000e+00, float [[TMP0]], float 1.000000e+00) +// CHECK-NOHONOR-NEXT: ret float [[TMP1]] +// float fun_default FUN(1) //CHECK-LABEL: define {{.*}} @_Z11fun_defaultf{{.*}} #if DEFAULT -//CHECK-DDEFAULT: call float @llvm.fmuladd{{.*}} #endif #if EBSTRICT // Note that backend wants constrained intrinsics used // throughout the function if they are needed anywhere in the function. // In that case, operations are built with constrained intrinsics operator // but using default settings for exception behavior and rounding mode. -//CHECK-DEBSTRICT: llvm.experimental.constrained.fmul{{.*}}tonearest{{.*}}strict #endif #if FAST -//CHECK-FAST: fmul fast float -//CHECK-FAST: fadd fast float #endif #pragma float_control(push) @@ -32,190 +66,530 @@ // Rule: precise must be enabled #pragma float_control(except, on) #endif - // CHECK-FAST: Function Attrs: mustprogress noinline nounwind optnone{{$$}} - // CHECK-DDEFAULT: Function Attrs: mustprogress noinline nounwind optnone strictfp{{$$}} - // CHECK-DEBSTRICT: Function Attrs: mustprogress noinline nounwind optnone strictfp{{$$}} - // CHECK-NOHONOR: Function Attrs: mustprogress noinline nounwind optnone strictfp{{$$}} +// CHECK-DDEFAULT-LABEL: define dso_local noundef float @_Z6exc_onf +// CHECK-DDEFAULT-SAME: (float noundef [[Z:%.*]]) #[[ATTR1:[0-9]+]] { +// CHECK-DDEFAULT-NEXT: entry: +// CHECK-DDEFAULT-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-DDEFAULT-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-DDEFAULT-NEXT: [[CONV:%.*]] = call float @llvm.experimental.constrained.sitofp.f32.i32(i32 2, metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR9:[0-9]+]] +// CHECK-DDEFAULT-NEXT: [[TMP0:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-DDEFAULT-NEXT: [[MUL:%.*]] = call float @llvm.experimental.constrained.fmul.f32(float [[CONV]], float [[TMP0]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR9]] +// CHECK-DDEFAULT-NEXT: [[CONV1:%.*]] = call float @llvm.experimental.constrained.sitofp.f32.i32(i32 2, metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR9]] +// CHECK-DDEFAULT-NEXT: [[ADD:%.*]] = call float @llvm.experimental.constrained.fadd.f32(float [[MUL]], float [[CONV1]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR9]] +// CHECK-DDEFAULT-NEXT: ret float [[ADD]] +// +// CHECK-DEBSTRICT-LABEL: define dso_local noundef float @_Z6exc_onf +// CHECK-DEBSTRICT-SAME: (float noundef [[Z:%.*]]) #[[ATTR0]] { +// CHECK-DEBSTRICT-NEXT: entry: +// CHECK-DEBSTRICT-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-DEBSTRICT-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-DEBSTRICT-NEXT: [[CONV:%.*]] = call float @llvm.experimental.constrained.sitofp.f32.i32(i32 2, metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR9]] +// CHECK-DEBSTRICT-NEXT: [[TMP0:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-DEBSTRICT-NEXT: [[MUL:%.*]] = call float @llvm.experimental.constrained.fmul.f32(float [[CONV]], float [[TMP0]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR9]] +// CHECK-DEBSTRICT-NEXT: [[CONV1:%.*]] = call float @llvm.experimental.constrained.sitofp.f32.i32(i32 2, metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR9]] +// CHECK-DEBSTRICT-NEXT: [[ADD:%.*]] = call float @llvm.experimental.constrained.fadd.f32(float [[MUL]], float [[CONV1]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR9]] +// CHECK-DEBSTRICT-NEXT: ret float [[ADD]] +// +// CHECK-FAST-LABEL: define dso_local noundef nofpclass(nan inf) float @_Z6exc_onf +// CHECK-FAST-SAME: (float noundef nofpclass(nan inf) [[Z:%.*]]) #[[ATTR0]] { +// CHECK-FAST-NEXT: entry: +// CHECK-FAST-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-FAST-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-FAST-NEXT: [[TMP0:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-FAST-NEXT: [[MUL:%.*]] = fmul fast float 2.000000e+00, [[TMP0]] +// CHECK-FAST-NEXT: [[ADD:%.*]] = fadd fast float [[MUL]], 2.000000e+00 +// CHECK-FAST-NEXT: ret float [[ADD]] +// +// CHECK-NOHONOR-LABEL: define dso_local noundef nofpclass(nan inf) float @_Z6exc_onf +// CHECK-NOHONOR-SAME: (float noundef nofpclass(nan inf) [[Z:%.*]]) #[[ATTR2:[0-9]+]] { +// CHECK-NOHONOR-NEXT: entry: +// CHECK-NOHONOR-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-NOHONOR-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-NOHONOR-NEXT: [[CONV:%.*]] = call nnan ninf float @llvm.experimental.constrained.sitofp.f32.i32(i32 2, metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR13:[0-9]+]] +// CHECK-NOHONOR-NEXT: [[TMP0:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-NOHONOR-NEXT: [[CONV1:%.*]] = call nnan ninf float @llvm.experimental.constrained.sitofp.f32.i32(i32 2, metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR13]] +// CHECK-NOHONOR-NEXT: [[TMP1:%.*]] = call nnan ninf float @llvm.experimental.constrained.fmuladd.f32(float [[CONV]], float [[TMP0]], float [[CONV1]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR13]] +// CHECK-NOHONOR-NEXT: ret float [[TMP1]] +// float exc_on FUN(2) //CHECK-LABEL: define {{.*}} @_Z6exc_onf{{.*}} #if DEFAULT -//CHECK-DDEFAULT: llvm.experimental.constrained.fmul{{.*}} #endif #if EBSTRICT -//CHECK-DEBSTRICT: llvm.experimental.constrained.fmuladd{{.*}}tonearest{{.*}}strict #endif #if NOHONOR -//CHECK-NOHONOR: nnan ninf float {{.*}}llvm.experimental.constrained.fmuladd{{.*}}tonearest{{.*}}strict #endif #if FAST //Not possible to enable float_control(except) in FAST mode. -//CHECK-FAST: fmul fast float -//CHECK-FAST: fadd fast float #endif #pragma float_control(pop) - // CHECK-DDEFAULT: Function Attrs: mustprogress noinline nounwind optnone{{$$}} - // CHECK-DEBSTRICT: Function Attrs: mustprogress noinline nounwind optnone strictfp{{$$}} - // CHECK-FAST: Function Attrs: mustprogress noinline nounwind optnone{{$$}} - // CHECK-NOHONOR: Function Attrs: mustprogress noinline nounwind optnone{{$$}} +// CHECK-DDEFAULT-LABEL: define dso_local noundef float @_Z7exc_popf +// CHECK-DDEFAULT-SAME: (float noundef [[Z:%.*]]) #[[ATTR0]] { +// CHECK-DDEFAULT-NEXT: entry: +// CHECK-DDEFAULT-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-DDEFAULT-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-DDEFAULT-NEXT: [[TMP0:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-DDEFAULT-NEXT: [[MUL:%.*]] = fmul float 5.000000e+00, [[TMP0]] +// CHECK-DDEFAULT-NEXT: [[ADD:%.*]] = fadd float [[MUL]], 5.000000e+00 +// CHECK-DDEFAULT-NEXT: ret float [[ADD]] +// +// CHECK-DEBSTRICT-LABEL: define dso_local noundef float @_Z7exc_popf +// CHECK-DEBSTRICT-SAME: (float noundef [[Z:%.*]]) #[[ATTR0]] { +// CHECK-DEBSTRICT-NEXT: entry: +// CHECK-DEBSTRICT-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-DEBSTRICT-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-DEBSTRICT-NEXT: [[CONV:%.*]] = call float @llvm.experimental.constrained.sitofp.f32.i32(i32 5, metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR9]] +// CHECK-DEBSTRICT-NEXT: [[TMP0:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-DEBSTRICT-NEXT: [[MUL:%.*]] = call float @llvm.experimental.constrained.fmul.f32(float [[CONV]], float [[TMP0]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR9]] +// CHECK-DEBSTRICT-NEXT: [[CONV1:%.*]] = call float @llvm.experimental.constrained.sitofp.f32.i32(i32 5, metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR9]] +// CHECK-DEBSTRICT-NEXT: [[ADD:%.*]] = call float @llvm.experimental.constrained.fadd.f32(float [[MUL]], float [[CONV1]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR9]] +// CHECK-DEBSTRICT-NEXT: ret float [[ADD]] +// +// CHECK-FAST-LABEL: define dso_local noundef nofpclass(nan inf) float @_Z7exc_popf +// CHECK-FAST-SAME: (float noundef nofpclass(nan inf) [[Z:%.*]]) #[[ATTR0]] { +// CHECK-FAST-NEXT: entry: +// CHECK-FAST-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-FAST-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-FAST-NEXT: [[TMP0:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-FAST-NEXT: [[MUL:%.*]] = fmul fast float 5.000000e+00, [[TMP0]] +// CHECK-FAST-NEXT: [[ADD:%.*]] = fadd fast float [[MUL]], 5.000000e+00 +// CHECK-FAST-NEXT: ret float [[ADD]] +// +// CHECK-NOHONOR-LABEL: define dso_local noundef nofpclass(nan inf) float @_Z7exc_popf +// CHECK-NOHONOR-SAME: (float noundef nofpclass(nan inf) [[Z:%.*]]) #[[ATTR0]] { +// CHECK-NOHONOR-NEXT: entry: +// CHECK-NOHONOR-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-NOHONOR-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-NOHONOR-NEXT: [[TMP0:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-NOHONOR-NEXT: [[TMP1:%.*]] = call nnan ninf float @llvm.fmuladd.f32(float 5.000000e+00, float [[TMP0]], float 5.000000e+00) +// CHECK-NOHONOR-NEXT: ret float [[TMP1]] +// float exc_pop FUN(5) //CHECK-LABEL: define {{.*}} @_Z7exc_popf{{.*}} #if DEFAULT -//CHECK-DDEFAULT: call float @llvm.fmuladd{{.*}} #endif #if EBSTRICT -//CHECK-DEBSTRICT: llvm.experimental.constrained.fmuladd{{.*}}tonearest{{.*}}strict #endif #if NOHONOR -//CHECK-NOHONOR: call nnan ninf float @llvm.fmuladd{{.*}} #endif #if FAST -//CHECK-FAST: fmul fast float -//CHECK-FAST: fadd fast float #endif #pragma float_control(except, off) +// CHECK-DDEFAULT-LABEL: define dso_local noundef float @_Z7exc_offf +// CHECK-DDEFAULT-SAME: (float noundef [[Z:%.*]]) #[[ATTR0]] { +// CHECK-DDEFAULT-NEXT: entry: +// CHECK-DDEFAULT-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-DDEFAULT-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-DDEFAULT-NEXT: [[TMP0:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-DDEFAULT-NEXT: [[MUL:%.*]] = fmul float 5.000000e+00, [[TMP0]] +// CHECK-DDEFAULT-NEXT: [[ADD:%.*]] = fadd float [[MUL]], 5.000000e+00 +// CHECK-DDEFAULT-NEXT: ret float [[ADD]] +// +// CHECK-DEBSTRICT-LABEL: define dso_local noundef float @_Z7exc_offf +// CHECK-DEBSTRICT-SAME: (float noundef [[Z:%.*]]) #[[ATTR2:[0-9]+]] { +// CHECK-DEBSTRICT-NEXT: entry: +// CHECK-DEBSTRICT-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-DEBSTRICT-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-DEBSTRICT-NEXT: [[TMP0:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-DEBSTRICT-NEXT: [[MUL:%.*]] = fmul float 5.000000e+00, [[TMP0]] +// CHECK-DEBSTRICT-NEXT: [[ADD:%.*]] = fadd float [[MUL]], 5.000000e+00 +// CHECK-DEBSTRICT-NEXT: ret float [[ADD]] +// +// CHECK-FAST-LABEL: define dso_local noundef nofpclass(nan inf) float @_Z7exc_offf +// CHECK-FAST-SAME: (float noundef nofpclass(nan inf) [[Z:%.*]]) #[[ATTR0]] { +// CHECK-FAST-NEXT: entry: +// CHECK-FAST-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-FAST-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-FAST-NEXT: [[TMP0:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-FAST-NEXT: [[MUL:%.*]] = fmul fast float 5.000000e+00, [[TMP0]] +// CHECK-FAST-NEXT: [[ADD:%.*]] = fadd fast float [[MUL]], 5.000000e+00 +// CHECK-FAST-NEXT: ret float [[ADD]] +// +// CHECK-NOHONOR-LABEL: define dso_local noundef nofpclass(nan inf) float @_Z7exc_offf +// CHECK-NOHONOR-SAME: (float noundef nofpclass(nan inf) [[Z:%.*]]) #[[ATTR0]] { +// CHECK-NOHONOR-NEXT: entry: +// CHECK-NOHONOR-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-NOHONOR-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-NOHONOR-NEXT: [[TMP0:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-NOHONOR-NEXT: [[TMP1:%.*]] = call nnan ninf float @llvm.fmuladd.f32(float 5.000000e+00, float [[TMP0]], float 5.000000e+00) +// CHECK-NOHONOR-NEXT: ret float [[TMP1]] +// float exc_off FUN(5) //CHECK-LABEL: define {{.*}} @_Z7exc_offf{{.*}} #if DEFAULT -//CHECK-DDEFAULT: call float @llvm.fmuladd{{.*}} #endif #if EBSTRICT -//CHECK-DEBSTRICT: call float @llvm.fmuladd{{.*}} #endif #if NOHONOR -//CHECK-NOHONOR: call nnan ninf float @llvm.fmuladd{{.*}} #endif #if FAST -//CHECK-FAST: fmul fast float -//CHECK-FAST: fadd fast float #endif #pragma float_control(precise, on, push) +// CHECK-DDEFAULT-LABEL: define dso_local noundef float @_Z10precise_onf +// CHECK-DDEFAULT-SAME: (float noundef [[Z:%.*]]) #[[ATTR0]] { +// CHECK-DDEFAULT-NEXT: entry: +// CHECK-DDEFAULT-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-DDEFAULT-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-DDEFAULT-NEXT: [[TMP0:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-DDEFAULT-NEXT: [[MUL:%.*]] = fmul float 3.000000e+00, [[TMP0]] +// CHECK-DDEFAULT-NEXT: [[ADD:%.*]] = fadd float [[MUL]], 3.000000e+00 +// CHECK-DDEFAULT-NEXT: ret float [[ADD]] +// +// CHECK-DEBSTRICT-LABEL: define dso_local noundef float @_Z10precise_onf +// CHECK-DEBSTRICT-SAME: (float noundef [[Z:%.*]]) #[[ATTR2]] { +// CHECK-DEBSTRICT-NEXT: entry: +// CHECK-DEBSTRICT-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-DEBSTRICT-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-DEBSTRICT-NEXT: [[TMP0:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-DEBSTRICT-NEXT: [[MUL:%.*]] = fmul float 3.000000e+00, [[TMP0]] +// CHECK-DEBSTRICT-NEXT: [[ADD:%.*]] = fadd float [[MUL]], 3.000000e+00 +// CHECK-DEBSTRICT-NEXT: ret float [[ADD]] +// +// CHECK-FAST-LABEL: define dso_local noundef nofpclass(nan inf) float @_Z10precise_onf +// CHECK-FAST-SAME: (float noundef nofpclass(nan inf) [[Z:%.*]]) #[[ATTR1:[0-9]+]] { +// CHECK-FAST-NEXT: entry: +// CHECK-FAST-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-FAST-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-FAST-NEXT: [[TMP0:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-FAST-NEXT: [[MUL:%.*]] = fmul float 3.000000e+00, [[TMP0]] +// CHECK-FAST-NEXT: [[ADD:%.*]] = fadd float [[MUL]], 3.000000e+00 +// CHECK-FAST-NEXT: ret float [[ADD]] +// +// CHECK-NOHONOR-LABEL: define dso_local noundef nofpclass(nan inf) float @_Z10precise_onf +// CHECK-NOHONOR-SAME: (float noundef nofpclass(nan inf) [[Z:%.*]]) #[[ATTR4:[0-9]+]] { +// CHECK-NOHONOR-NEXT: entry: +// CHECK-NOHONOR-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-NOHONOR-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-NOHONOR-NEXT: [[TMP0:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-NOHONOR-NEXT: [[TMP1:%.*]] = call float @llvm.fmuladd.f32(float 3.000000e+00, float [[TMP0]], float 3.000000e+00) +// CHECK-NOHONOR-NEXT: ret float [[TMP1]] +// float precise_on FUN(3) //CHECK-LABEL: define {{.*}} @_Z10precise_onf{{.*}} #if DEFAULT -//CHECK-DDEFAULT: float {{.*}}llvm.fmuladd{{.*}} #endif #if EBSTRICT -//CHECK-DEBSTRICT: float {{.*}}llvm.fmuladd{{.*}} #endif #if NOHONOR // If precise is pushed then all fast-math should be off! -//CHECK-NOHONOR: call float {{.*}}llvm.fmuladd{{.*}} #endif #if FAST -//CHECK-FAST: float {{.*}}llvm.fmuladd{{.*}} #endif #pragma float_control(pop) +// CHECK-DDEFAULT-LABEL: define dso_local noundef float @_Z11precise_popf +// CHECK-DDEFAULT-SAME: (float noundef [[Z:%.*]]) #[[ATTR0]] { +// CHECK-DDEFAULT-NEXT: entry: +// CHECK-DDEFAULT-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-DDEFAULT-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-DDEFAULT-NEXT: [[TMP0:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-DDEFAULT-NEXT: [[MUL:%.*]] = fmul float 3.000000e+00, [[TMP0]] +// CHECK-DDEFAULT-NEXT: [[ADD:%.*]] = fadd float [[MUL]], 3.000000e+00 +// CHECK-DDEFAULT-NEXT: ret float [[ADD]] +// +// CHECK-DEBSTRICT-LABEL: define dso_local noundef float @_Z11precise_popf +// CHECK-DEBSTRICT-SAME: (float noundef [[Z:%.*]]) #[[ATTR2]] { +// CHECK-DEBSTRICT-NEXT: entry: +// CHECK-DEBSTRICT-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-DEBSTRICT-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-DEBSTRICT-NEXT: [[TMP0:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-DEBSTRICT-NEXT: [[MUL:%.*]] = fmul float 3.000000e+00, [[TMP0]] +// CHECK-DEBSTRICT-NEXT: [[ADD:%.*]] = fadd float [[MUL]], 3.000000e+00 +// CHECK-DEBSTRICT-NEXT: ret float [[ADD]] +// +// CHECK-FAST-LABEL: define dso_local noundef nofpclass(nan inf) float @_Z11precise_popf +// CHECK-FAST-SAME: (float noundef nofpclass(nan inf) [[Z:%.*]]) #[[ATTR0]] { +// CHECK-FAST-NEXT: entry: +// CHECK-FAST-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-FAST-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-FAST-NEXT: [[TMP0:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-FAST-NEXT: [[MUL:%.*]] = fmul fast float 3.000000e+00, [[TMP0]] +// CHECK-FAST-NEXT: [[ADD:%.*]] = fadd fast float [[MUL]], 3.000000e+00 +// CHECK-FAST-NEXT: ret float [[ADD]] +// +// CHECK-NOHONOR-LABEL: define dso_local noundef nofpclass(nan inf) float @_Z11precise_popf +// CHECK-NOHONOR-SAME: (float noundef nofpclass(nan inf) [[Z:%.*]]) #[[ATTR0]] { +// CHECK-NOHONOR-NEXT: entry: +// CHECK-NOHONOR-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-NOHONOR-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-NOHONOR-NEXT: [[TMP0:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-NOHONOR-NEXT: [[TMP1:%.*]] = call nnan ninf float @llvm.fmuladd.f32(float 3.000000e+00, float [[TMP0]], float 3.000000e+00) +// CHECK-NOHONOR-NEXT: ret float [[TMP1]] +// float precise_pop FUN(3) //CHECK-LABEL: define {{.*}} @_Z11precise_popf{{.*}} #if DEFAULT -//CHECK-DDEFAULT: float {{.*}}llvm.fmuladd{{.*}} #endif #if EBSTRICT -//CHECK-DEBSTRICT: float {{.*}}llvm.fmuladd{{.*}} #endif #if NOHONOR -//CHECK-NOHONOR: call nnan ninf float @llvm.fmuladd{{.*}} #endif #if FAST -//CHECK-FAST: fmul fast float -//CHECK-FAST: fadd fast float #endif #pragma float_control(precise, off) +// CHECK-DDEFAULT-LABEL: define dso_local noundef float @_Z11precise_offf +// CHECK-DDEFAULT-SAME: (float noundef [[Z:%.*]]) #[[ATTR0]] { +// CHECK-DDEFAULT-NEXT: entry: +// CHECK-DDEFAULT-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-DDEFAULT-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-DDEFAULT-NEXT: [[TMP0:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-DDEFAULT-NEXT: [[MUL:%.*]] = fmul fast float 4.000000e+00, [[TMP0]] +// CHECK-DDEFAULT-NEXT: [[ADD:%.*]] = fadd fast float [[MUL]], 4.000000e+00 +// CHECK-DDEFAULT-NEXT: ret float [[ADD]] +// +// CHECK-DEBSTRICT-LABEL: define dso_local noundef float @_Z11precise_offf +// CHECK-DEBSTRICT-SAME: (float noundef [[Z:%.*]]) #[[ATTR2]] { +// CHECK-DEBSTRICT-NEXT: entry: +// CHECK-DEBSTRICT-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-DEBSTRICT-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-DEBSTRICT-NEXT: [[TMP0:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-DEBSTRICT-NEXT: [[MUL:%.*]] = fmul fast float 4.000000e+00, [[TMP0]] +// CHECK-DEBSTRICT-NEXT: [[ADD:%.*]] = fadd fast float [[MUL]], 4.000000e+00 +// CHECK-DEBSTRICT-NEXT: ret float [[ADD]] +// +// CHECK-FAST-LABEL: define dso_local noundef nofpclass(nan inf) float @_Z11precise_offf +// CHECK-FAST-SAME: (float noundef nofpclass(nan inf) [[Z:%.*]]) #[[ATTR0]] { +// CHECK-FAST-NEXT: entry: +// CHECK-FAST-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-FAST-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-FAST-NEXT: [[TMP0:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-FAST-NEXT: [[MUL:%.*]] = fmul fast float 4.000000e+00, [[TMP0]] +// CHECK-FAST-NEXT: [[ADD:%.*]] = fadd fast float [[MUL]], 4.000000e+00 +// CHECK-FAST-NEXT: ret float [[ADD]] +// +// CHECK-NOHONOR-LABEL: define dso_local noundef nofpclass(nan inf) float @_Z11precise_offf +// CHECK-NOHONOR-SAME: (float noundef nofpclass(nan inf) [[Z:%.*]]) #[[ATTR0]] { +// CHECK-NOHONOR-NEXT: entry: +// CHECK-NOHONOR-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-NOHONOR-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-NOHONOR-NEXT: [[TMP0:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-NOHONOR-NEXT: [[MUL:%.*]] = fmul fast float 4.000000e+00, [[TMP0]] +// CHECK-NOHONOR-NEXT: [[ADD:%.*]] = fadd fast float [[MUL]], 4.000000e+00 +// CHECK-NOHONOR-NEXT: ret float [[ADD]] +// float precise_off FUN(4) //CHECK-LABEL: define {{.*}} @_Z11precise_offf{{.*}} #if DEFAULT // Note: precise_off enables fp_contract=fast and the instructions // generated do not include the contract flag, although it was enabled // in IRBuilder. -//CHECK-DDEFAULT: fmul fast float -//CHECK-DDEFAULT: fadd fast float #endif #if EBSTRICT -//CHECK-DEBSTRICT: fmul fast float -//CHECK-DEBSTRICT: fadd fast float #endif #if NOHONOR // fast math should be enabled, and contract should be fast -//CHECK-NOHONOR: fmul fast float -//CHECK-NOHONOR: fadd fast float #endif #if FAST -//CHECK-FAST: fmul fast float -//CHECK-FAST: fadd fast float #endif #pragma float_control(precise, on) +// CHECK-DDEFAULT-LABEL: define dso_local noundef float @_Z11precise_on2f +// CHECK-DDEFAULT-SAME: (float noundef [[Z:%.*]]) #[[ATTR0]] { +// CHECK-DDEFAULT-NEXT: entry: +// CHECK-DDEFAULT-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-DDEFAULT-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-DDEFAULT-NEXT: [[TMP0:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-DDEFAULT-NEXT: [[MUL:%.*]] = fmul float 3.000000e+00, [[TMP0]] +// CHECK-DDEFAULT-NEXT: [[ADD:%.*]] = fadd float [[MUL]], 3.000000e+00 +// CHECK-DDEFAULT-NEXT: ret float [[ADD]] +// +// CHECK-DEBSTRICT-LABEL: define dso_local noundef float @_Z11precise_on2f +// CHECK-DEBSTRICT-SAME: (float noundef [[Z:%.*]]) #[[ATTR2]] { +// CHECK-DEBSTRICT-NEXT: entry: +// CHECK-DEBSTRICT-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-DEBSTRICT-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-DEBSTRICT-NEXT: [[TMP0:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-DEBSTRICT-NEXT: [[MUL:%.*]] = fmul float 3.000000e+00, [[TMP0]] +// CHECK-DEBSTRICT-NEXT: [[ADD:%.*]] = fadd float [[MUL]], 3.000000e+00 +// CHECK-DEBSTRICT-NEXT: ret float [[ADD]] +// +// CHECK-FAST-LABEL: define dso_local noundef nofpclass(nan inf) float @_Z11precise_on2f +// CHECK-FAST-SAME: (float noundef nofpclass(nan inf) [[Z:%.*]]) #[[ATTR1]] { +// CHECK-FAST-NEXT: entry: +// CHECK-FAST-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-FAST-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-FAST-NEXT: [[TMP0:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-FAST-NEXT: [[MUL:%.*]] = fmul float 3.000000e+00, [[TMP0]] +// CHECK-FAST-NEXT: [[ADD:%.*]] = fadd float [[MUL]], 3.000000e+00 +// CHECK-FAST-NEXT: ret float [[ADD]] +// +// CHECK-NOHONOR-LABEL: define dso_local noundef nofpclass(nan inf) float @_Z11precise_on2f +// CHECK-NOHONOR-SAME: (float noundef nofpclass(nan inf) [[Z:%.*]]) #[[ATTR4]] { +// CHECK-NOHONOR-NEXT: entry: +// CHECK-NOHONOR-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-NOHONOR-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-NOHONOR-NEXT: [[TMP0:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-NOHONOR-NEXT: [[TMP1:%.*]] = call float @llvm.fmuladd.f32(float 3.000000e+00, float [[TMP0]], float 3.000000e+00) +// CHECK-NOHONOR-NEXT: ret float [[TMP1]] +// float precise_on2 FUN(3) //CHECK-LABEL: define {{.*}} @_Z11precise_on2f{{.*}} #if DEFAULT -//CHECK-DDEFAULT: llvm.fmuladd{{.*}} #endif #if EBSTRICT -//CHECK-DEBSTRICT: float {{.*}}llvm.fmuladd{{.*}} #endif #if NOHONOR // fast math should be off, and contract should be on -//CHECK-NOHONOR: float {{.*}}llvm.fmuladd{{.*}} #endif #if FAST -//CHECK-FAST: float {{.*}}llvm.fmuladd{{.*}} #endif #pragma float_control(push) +// CHECK-DDEFAULT-LABEL: define dso_local noundef float @_Z12precise_pushf +// CHECK-DDEFAULT-SAME: (float noundef [[Z:%.*]]) #[[ATTR0]] { +// CHECK-DDEFAULT-NEXT: entry: +// CHECK-DDEFAULT-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-DDEFAULT-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-DDEFAULT-NEXT: [[TMP0:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-DDEFAULT-NEXT: [[MUL:%.*]] = fmul float 3.000000e+00, [[TMP0]] +// CHECK-DDEFAULT-NEXT: [[ADD:%.*]] = fadd float [[MUL]], 3.000000e+00 +// CHECK-DDEFAULT-NEXT: ret float [[ADD]] +// +// CHECK-DEBSTRICT-LABEL: define dso_local noundef float @_Z12precise_pushf +// CHECK-DEBSTRICT-SAME: (float noundef [[Z:%.*]]) #[[ATTR2]] { +// CHECK-DEBSTRICT-NEXT: entry: +// CHECK-DEBSTRICT-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-DEBSTRICT-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-DEBSTRICT-NEXT: [[TMP0:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-DEBSTRICT-NEXT: [[MUL:%.*]] = fmul float 3.000000e+00, [[TMP0]] +// CHECK-DEBSTRICT-NEXT: [[ADD:%.*]] = fadd float [[MUL]], 3.000000e+00 +// CHECK-DEBSTRICT-NEXT: ret float [[ADD]] +// +// CHECK-FAST-LABEL: define dso_local noundef nofpclass(nan inf) float @_Z12precise_pushf +// CHECK-FAST-SAME: (float noundef nofpclass(nan inf) [[Z:%.*]]) #[[ATTR1]] { +// CHECK-FAST-NEXT: entry: +// CHECK-FAST-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-FAST-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-FAST-NEXT: [[TMP0:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-FAST-NEXT: [[MUL:%.*]] = fmul float 3.000000e+00, [[TMP0]] +// CHECK-FAST-NEXT: [[ADD:%.*]] = fadd float [[MUL]], 3.000000e+00 +// CHECK-FAST-NEXT: ret float [[ADD]] +// +// CHECK-NOHONOR-LABEL: define dso_local noundef nofpclass(nan inf) float @_Z12precise_pushf +// CHECK-NOHONOR-SAME: (float noundef nofpclass(nan inf) [[Z:%.*]]) #[[ATTR4]] { +// CHECK-NOHONOR-NEXT: entry: +// CHECK-NOHONOR-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-NOHONOR-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-NOHONOR-NEXT: [[TMP0:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-NOHONOR-NEXT: [[TMP1:%.*]] = call float @llvm.fmuladd.f32(float 3.000000e+00, float [[TMP0]], float 3.000000e+00) +// CHECK-NOHONOR-NEXT: ret float [[TMP1]] +// float precise_push FUN(3) //CHECK-LABEL: define {{.*}} @_Z12precise_pushf{{.*}} #if DEFAULT -//CHECK-DDEFAULT: llvm.fmuladd{{.*}} #endif #if EBSTRICT -//CHECK-DEBSTRICT: float {{.*}}llvm.fmuladd{{.*}} #endif #if NOHONOR -//CHECK-NOHONOR: float {{.*}}llvm.fmuladd{{.*}} #endif #if FAST -//CHECK-FAST: float {{.*}}llvm.fmuladd{{.*}} #endif #pragma float_control(precise, off) +// CHECK-DDEFAULT-LABEL: define dso_local noundef float @_Z12precise_off2f +// CHECK-DDEFAULT-SAME: (float noundef [[Z:%.*]]) #[[ATTR0]] { +// CHECK-DDEFAULT-NEXT: entry: +// CHECK-DDEFAULT-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-DDEFAULT-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-DDEFAULT-NEXT: [[TMP0:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-DDEFAULT-NEXT: [[MUL:%.*]] = fmul fast float 4.000000e+00, [[TMP0]] +// CHECK-DDEFAULT-NEXT: [[ADD:%.*]] = fadd fast float [[MUL]], 4.000000e+00 +// CHECK-DDEFAULT-NEXT: ret float [[ADD]] +// +// CHECK-DEBSTRICT-LABEL: define dso_local noundef float @_Z12precise_off2f +// CHECK-DEBSTRICT-SAME: (float noundef [[Z:%.*]]) #[[ATTR2]] { +// CHECK-DEBSTRICT-NEXT: entry: +// CHECK-DEBSTRICT-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-DEBSTRICT-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-DEBSTRICT-NEXT: [[TMP0:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-DEBSTRICT-NEXT: [[MUL:%.*]] = fmul fast float 4.000000e+00, [[TMP0]] +// CHECK-DEBSTRICT-NEXT: [[ADD:%.*]] = fadd fast float [[MUL]], 4.000000e+00 +// CHECK-DEBSTRICT-NEXT: ret float [[ADD]] +// +// CHECK-FAST-LABEL: define dso_local noundef nofpclass(nan inf) float @_Z12precise_off2f +// CHECK-FAST-SAME: (float noundef nofpclass(nan inf) [[Z:%.*]]) #[[ATTR0]] { +// CHECK-FAST-NEXT: entry: +// CHECK-FAST-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-FAST-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-FAST-NEXT: [[TMP0:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-FAST-NEXT: [[MUL:%.*]] = fmul fast float 4.000000e+00, [[TMP0]] +// CHECK-FAST-NEXT: [[ADD:%.*]] = fadd fast float [[MUL]], 4.000000e+00 +// CHECK-FAST-NEXT: ret float [[ADD]] +// +// CHECK-NOHONOR-LABEL: define dso_local noundef nofpclass(nan inf) float @_Z12precise_off2f +// CHECK-NOHONOR-SAME: (float noundef nofpclass(nan inf) [[Z:%.*]]) #[[ATTR0]] { +// CHECK-NOHONOR-NEXT: entry: +// CHECK-NOHONOR-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-NOHONOR-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-NOHONOR-NEXT: [[TMP0:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-NOHONOR-NEXT: [[MUL:%.*]] = fmul fast float 4.000000e+00, [[TMP0]] +// CHECK-NOHONOR-NEXT: [[ADD:%.*]] = fadd fast float [[MUL]], 4.000000e+00 +// CHECK-NOHONOR-NEXT: ret float [[ADD]] +// float precise_off2 FUN(4) //CHECK-LABEL: define {{.*}} @_Z12precise_off2f{{.*}} #if DEFAULT -//CHECK-DDEFAULT: fmul fast float -//CHECK-DDEFAULT: fadd fast float #endif #if EBSTRICT -//CHECK-DEBSTRICT: fmul fast float -//CHECK-DEBSTRICT: fadd fast float #endif #if NOHONOR // fast math settings since precise is off -//CHECK-NOHONOR: fmul fast float -//CHECK-NOHONOR: fadd fast float #endif #if FAST -//CHECK-FAST: fmul fast float -//CHECK-FAST: fadd fast float #endif #pragma float_control(pop) +// CHECK-DDEFAULT-LABEL: define dso_local noundef float @_Z12precise_pop2f +// CHECK-DDEFAULT-SAME: (float noundef [[Z:%.*]]) #[[ATTR0]] { +// CHECK-DDEFAULT-NEXT: entry: +// CHECK-DDEFAULT-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-DDEFAULT-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-DDEFAULT-NEXT: [[TMP0:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-DDEFAULT-NEXT: [[MUL:%.*]] = fmul float 3.000000e+00, [[TMP0]] +// CHECK-DDEFAULT-NEXT: [[ADD:%.*]] = fadd float [[MUL]], 3.000000e+00 +// CHECK-DDEFAULT-NEXT: ret float [[ADD]] +// +// CHECK-DEBSTRICT-LABEL: define dso_local noundef float @_Z12precise_pop2f +// CHECK-DEBSTRICT-SAME: (float noundef [[Z:%.*]]) #[[ATTR2]] { +// CHECK-DEBSTRICT-NEXT: entry: +// CHECK-DEBSTRICT-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-DEBSTRICT-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-DEBSTRICT-NEXT: [[TMP0:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-DEBSTRICT-NEXT: [[MUL:%.*]] = fmul float 3.000000e+00, [[TMP0]] +// CHECK-DEBSTRICT-NEXT: [[ADD:%.*]] = fadd float [[MUL]], 3.000000e+00 +// CHECK-DEBSTRICT-NEXT: ret float [[ADD]] +// +// CHECK-FAST-LABEL: define dso_local noundef nofpclass(nan inf) float @_Z12precise_pop2f +// CHECK-FAST-SAME: (float noundef nofpclass(nan inf) [[Z:%.*]]) #[[ATTR1]] { +// CHECK-FAST-NEXT: entry: +// CHECK-FAST-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-FAST-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-FAST-NEXT: [[TMP0:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-FAST-NEXT: [[MUL:%.*]] = fmul float 3.000000e+00, [[TMP0]] +// CHECK-FAST-NEXT: [[ADD:%.*]] = fadd float [[MUL]], 3.000000e+00 +// CHECK-FAST-NEXT: ret float [[ADD]] +// +// CHECK-NOHONOR-LABEL: define dso_local noundef nofpclass(nan inf) float @_Z12precise_pop2f +// CHECK-NOHONOR-SAME: (float noundef nofpclass(nan inf) [[Z:%.*]]) #[[ATTR4]] { +// CHECK-NOHONOR-NEXT: entry: +// CHECK-NOHONOR-NEXT: [[Z_ADDR:%.*]] = alloca float, align 4 +// CHECK-NOHONOR-NEXT: store float [[Z]], ptr [[Z_ADDR]], align 4 +// CHECK-NOHONOR-NEXT: [[TMP0:%.*]] = load float, ptr [[Z_ADDR]], align 4 +// CHECK-NOHONOR-NEXT: [[TMP1:%.*]] = call float @llvm.fmuladd.f32(float 3.000000e+00, float [[TMP0]], float 3.000000e+00) +// CHECK-NOHONOR-NEXT: ret float [[TMP1]] +// float precise_pop2 FUN(3) //CHECK-LABEL: define {{.*}} @_Z12precise_pop2f{{.*}} #if DEFAULT -//CHECK-DDEFAULT: llvm.fmuladd{{.*}} #endif #if EBSTRICT -//CHECK-DEBSTRICT: float {{.*}}llvm.fmuladd{{.*}} #endif #if NOHONOR -//CHECK-NOHONOR: float {{.*}}llvm.fmuladd{{.*}} #endif #if FAST -//CHECK-FAST: float {{.*}}llvm.fmuladd{{.*}} #endif #ifndef FAST @@ -223,33 +597,93 @@ #pragma float_control(except, on) #endif float y(); -// CHECK-DDEFAULT: Function Attrs: mustprogress noinline nounwind optnone{{$$}} -// CHECK-DEBSTRICT: Function Attrs: noinline nounwind optnone strictfp{{$$}} -// CHECK-FAST: Function Attrs: mustprogress noinline nounwind optnone{{$$}} -// CHECK-NOHONOR: Function Attrs: mustprogress noinline nounwind optnone{{$$}} +// CHECK-DDEFAULT-LABEL: define linkonce_odr void @_ZN2ONC1Ev +// CHECK-DDEFAULT-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR4:[0-9]+]] comdat align 2 { +// CHECK-DDEFAULT-NEXT: entry: +// CHECK-DDEFAULT-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-DDEFAULT-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 +// CHECK-DDEFAULT-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// CHECK-DDEFAULT-NEXT: call void @_ZN2ONC2Ev(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]]) +// CHECK-DDEFAULT-NEXT: ret void +// +// CHECK-DEBSTRICT-LABEL: define linkonce_odr void @_ZN2ONC1Ev +// CHECK-DEBSTRICT-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR4:[0-9]+]] comdat align 2 { +// CHECK-DEBSTRICT-NEXT: entry: +// CHECK-DEBSTRICT-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-DEBSTRICT-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 +// CHECK-DEBSTRICT-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// CHECK-DEBSTRICT-NEXT: call void @_ZN2ONC2Ev(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]]) +// CHECK-DEBSTRICT-NEXT: ret void +// +// CHECK-FAST-LABEL: define linkonce_odr void @_ZN2ONC1Ev +// CHECK-FAST-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR3:[0-9]+]] comdat align 2 { +// CHECK-FAST-NEXT: entry: +// CHECK-FAST-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-FAST-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 +// CHECK-FAST-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// CHECK-FAST-NEXT: call void @_ZN2ONC2Ev(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]]) +// CHECK-FAST-NEXT: ret void +// +// CHECK-NOHONOR-LABEL: define linkonce_odr void @_ZN2ONC1Ev +// CHECK-NOHONOR-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR6:[0-9]+]] comdat align 2 { +// CHECK-NOHONOR-NEXT: entry: +// CHECK-NOHONOR-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NOHONOR-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 +// CHECK-NOHONOR-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// CHECK-NOHONOR-NEXT: call void @_ZN2ONC2Ev(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]]) +// CHECK-NOHONOR-NEXT: ret void +// class ON { // Settings for top level class initializer use program source setting. float z = 2 + y() * 7; //CHECK-LABEL: define {{.*}} void @_ZN2ONC2Ev{{.*}} #if DEFAULT -// CHECK-DDEFAULT: llvm.experimental.constrained.fmul{{.*}}tonearest{{.*}}strict #endif #if EBSTRICT -// CHECK-DEBSTRICT: llvm.experimental.constrained.fmul{{.*}}tonearest{{.*}}strict #endif #if NOHONOR -// CHECK-NOHONOR: llvm.experimental.constrained.fmul{{.*}}tonearest{{.*}}strict #endif #if FAST -// CHECK-FAST: float {{.*}}llvm.fmuladd{{.*}} #endif }; ON on; #pragma float_control(except, off) -// CHECK-DDEFAULT: Function Attrs: noinline nounwind optnone{{$$}} -// CHECK-DEBSTRICT: Function Attrs: noinline nounwind optnone{{$$}} -// CHECK-FAST: Function Attrs: noinline nounwind optnone{{$$}} -// CHECK-NOHONOR: Function Attrs: noinline nounwind optnone{{$$}} +// CHECK-DDEFAULT-LABEL: define linkonce_odr void @_ZN3OFFC1Ev +// CHECK-DDEFAULT-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR5:[0-9]+]] comdat align 2 { +// CHECK-DDEFAULT-NEXT: entry: +// CHECK-DDEFAULT-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-DDEFAULT-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 +// CHECK-DDEFAULT-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// CHECK-DDEFAULT-NEXT: call void @_ZN3OFFC2Ev(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]]) +// CHECK-DDEFAULT-NEXT: ret void +// +// CHECK-DEBSTRICT-LABEL: define linkonce_odr void @_ZN3OFFC1Ev +// CHECK-DEBSTRICT-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR5:[0-9]+]] comdat align 2 { +// CHECK-DEBSTRICT-NEXT: entry: +// CHECK-DEBSTRICT-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-DEBSTRICT-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 +// CHECK-DEBSTRICT-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// CHECK-DEBSTRICT-NEXT: call void @_ZN3OFFC2Ev(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]]) +// CHECK-DEBSTRICT-NEXT: ret void +// +// CHECK-FAST-LABEL: define linkonce_odr void @_ZN3OFFC1Ev +// CHECK-FAST-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 { +// CHECK-FAST-NEXT: entry: +// CHECK-FAST-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-FAST-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 +// CHECK-FAST-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// CHECK-FAST-NEXT: call void @_ZN3OFFC2Ev(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]]) +// CHECK-FAST-NEXT: ret void +// +// CHECK-NOHONOR-LABEL: define linkonce_odr void @_ZN3OFFC1Ev +// CHECK-NOHONOR-SAME: (ptr noundef nonnull align 4 dereferenceable(4) [[THIS:%.*]]) unnamed_addr #[[ATTR7:[0-9]+]] comdat align 2 { +// CHECK-NOHONOR-NEXT: entry: +// CHECK-NOHONOR-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NOHONOR-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 +// CHECK-NOHONOR-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// CHECK-NOHONOR-NEXT: call void @_ZN3OFFC2Ev(ptr noundef nonnull align 4 dereferenceable(4) [[THIS1]]) +// CHECK-NOHONOR-NEXT: ret void +// class OFF { float w = 2 + y() * 7; // CHECK-LABEL: define {{.*}} void @_ZN3OFFC2Ev{{.*}} @@ -261,11 +695,163 @@ struct MyComplex { float xx; float yy; +// CHECK-DDEFAULT-LABEL: define linkonce_odr void @_ZN9MyComplexC1Eff +// CHECK-DDEFAULT-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]], float noundef [[X:%.*]], float noundef [[Y:%.*]]) unnamed_addr #[[ATTR5]] comdat align 2 { +// CHECK-DDEFAULT-NEXT: entry: +// CHECK-DDEFAULT-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-DDEFAULT-NEXT: [[X_ADDR:%.*]] = alloca float, align 4 +// CHECK-DDEFAULT-NEXT: [[Y_ADDR:%.*]] = alloca float, align 4 +// CHECK-DDEFAULT-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 +// CHECK-DDEFAULT-NEXT: store float [[X]], ptr [[X_ADDR]], align 4 +// CHECK-DDEFAULT-NEXT: store float [[Y]], ptr [[Y_ADDR]], align 4 +// CHECK-DDEFAULT-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// CHECK-DDEFAULT-NEXT: [[TMP0:%.*]] = load float, ptr [[X_ADDR]], align 4 +// CHECK-DDEFAULT-NEXT: [[TMP1:%.*]] = load float, ptr [[Y_ADDR]], align 4 +// CHECK-DDEFAULT-NEXT: call void @_ZN9MyComplexC2Eff(ptr noundef nonnull align 4 dereferenceable(8) [[THIS1]], float noundef [[TMP0]], float noundef [[TMP1]]) +// CHECK-DDEFAULT-NEXT: ret void +// +// CHECK-DEBSTRICT-LABEL: define linkonce_odr void @_ZN9MyComplexC1Eff +// CHECK-DEBSTRICT-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]], float noundef [[X:%.*]], float noundef [[Y:%.*]]) unnamed_addr #[[ATTR5]] comdat align 2 { +// CHECK-DEBSTRICT-NEXT: entry: +// CHECK-DEBSTRICT-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-DEBSTRICT-NEXT: [[X_ADDR:%.*]] = alloca float, align 4 +// CHECK-DEBSTRICT-NEXT: [[Y_ADDR:%.*]] = alloca float, align 4 +// CHECK-DEBSTRICT-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 +// CHECK-DEBSTRICT-NEXT: store float [[X]], ptr [[X_ADDR]], align 4 +// CHECK-DEBSTRICT-NEXT: store float [[Y]], ptr [[Y_ADDR]], align 4 +// CHECK-DEBSTRICT-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// CHECK-DEBSTRICT-NEXT: [[TMP0:%.*]] = load float, ptr [[X_ADDR]], align 4 +// CHECK-DEBSTRICT-NEXT: [[TMP1:%.*]] = load float, ptr [[Y_ADDR]], align 4 +// CHECK-DEBSTRICT-NEXT: call void @_ZN9MyComplexC2Eff(ptr noundef nonnull align 4 dereferenceable(8) [[THIS1]], float noundef [[TMP0]], float noundef [[TMP1]]) +// CHECK-DEBSTRICT-NEXT: ret void +// +// CHECK-FAST-LABEL: define linkonce_odr void @_ZN9MyComplexC1Eff +// CHECK-FAST-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]], float noundef nofpclass(nan inf) [[X:%.*]], float noundef nofpclass(nan inf) [[Y:%.*]]) unnamed_addr #[[ATTR3]] comdat align 2 { +// CHECK-FAST-NEXT: entry: +// CHECK-FAST-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-FAST-NEXT: [[X_ADDR:%.*]] = alloca float, align 4 +// CHECK-FAST-NEXT: [[Y_ADDR:%.*]] = alloca float, align 4 +// CHECK-FAST-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 +// CHECK-FAST-NEXT: store float [[X]], ptr [[X_ADDR]], align 4 +// CHECK-FAST-NEXT: store float [[Y]], ptr [[Y_ADDR]], align 4 +// CHECK-FAST-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// CHECK-FAST-NEXT: [[TMP0:%.*]] = load float, ptr [[X_ADDR]], align 4 +// CHECK-FAST-NEXT: [[TMP1:%.*]] = load float, ptr [[Y_ADDR]], align 4 +// CHECK-FAST-NEXT: call void @_ZN9MyComplexC2Eff(ptr noundef nonnull align 4 dereferenceable(8) [[THIS1]], float noundef nofpclass(nan inf) [[TMP0]], float noundef nofpclass(nan inf) [[TMP1]]) +// CHECK-FAST-NEXT: ret void +// +// CHECK-NOHONOR-LABEL: define linkonce_odr void @_ZN9MyComplexC1Eff +// CHECK-NOHONOR-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]], float noundef nofpclass(nan inf) [[X:%.*]], float noundef nofpclass(nan inf) [[Y:%.*]]) unnamed_addr #[[ATTR7]] comdat align 2 { +// CHECK-NOHONOR-NEXT: entry: +// CHECK-NOHONOR-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NOHONOR-NEXT: [[X_ADDR:%.*]] = alloca float, align 4 +// CHECK-NOHONOR-NEXT: [[Y_ADDR:%.*]] = alloca float, align 4 +// CHECK-NOHONOR-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 +// CHECK-NOHONOR-NEXT: store float [[X]], ptr [[X_ADDR]], align 4 +// CHECK-NOHONOR-NEXT: store float [[Y]], ptr [[Y_ADDR]], align 4 +// CHECK-NOHONOR-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// CHECK-NOHONOR-NEXT: [[TMP0:%.*]] = load float, ptr [[X_ADDR]], align 4 +// CHECK-NOHONOR-NEXT: [[TMP1:%.*]] = load float, ptr [[Y_ADDR]], align 4 +// CHECK-NOHONOR-NEXT: call void @_ZN9MyComplexC2Eff(ptr noundef nonnull align 4 dereferenceable(8) [[THIS1]], float noundef nofpclass(nan inf) [[TMP0]], float noundef nofpclass(nan inf) [[TMP1]]) +// CHECK-NOHONOR-NEXT: ret void +// MyComplex(float x, float y) { xx = x; yy = y; } MyComplex() {} +// CHECK-DDEFAULT-LABEL: define linkonce_odr <2 x float> @_ZNK9MyComplexplES_ +// CHECK-DDEFAULT-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]], <2 x float> [[OTHER_COERCE:%.*]]) #[[ATTR6:[0-9]+]] comdat align 2 { +// CHECK-DDEFAULT-NEXT: entry: +// CHECK-DDEFAULT-NEXT: [[RETVAL:%.*]] = alloca [[STRUCT_MYCOMPLEX:%.*]], align 4 +// CHECK-DDEFAULT-NEXT: [[OTHER:%.*]] = alloca [[STRUCT_MYCOMPLEX]], align 4 +// CHECK-DDEFAULT-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-DDEFAULT-NEXT: store <2 x float> [[OTHER_COERCE]], ptr [[OTHER]], align 4 +// CHECK-DDEFAULT-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 +// CHECK-DDEFAULT-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// CHECK-DDEFAULT-NEXT: [[XX:%.*]] = getelementptr inbounds [[STRUCT_MYCOMPLEX]], ptr [[THIS1]], i32 0, i32 0 +// CHECK-DDEFAULT-NEXT: [[TMP0:%.*]] = load float, ptr [[XX]], align 4 +// CHECK-DDEFAULT-NEXT: [[XX2:%.*]] = getelementptr inbounds [[STRUCT_MYCOMPLEX]], ptr [[OTHER]], i32 0, i32 0 +// CHECK-DDEFAULT-NEXT: [[TMP1:%.*]] = load float, ptr [[XX2]], align 4 +// CHECK-DDEFAULT-NEXT: [[ADD:%.*]] = fadd reassoc float [[TMP0]], [[TMP1]] +// CHECK-DDEFAULT-NEXT: [[YY:%.*]] = getelementptr inbounds [[STRUCT_MYCOMPLEX]], ptr [[THIS1]], i32 0, i32 1 +// CHECK-DDEFAULT-NEXT: [[TMP2:%.*]] = load float, ptr [[YY]], align 4 +// CHECK-DDEFAULT-NEXT: [[YY3:%.*]] = getelementptr inbounds [[STRUCT_MYCOMPLEX]], ptr [[OTHER]], i32 0, i32 1 +// CHECK-DDEFAULT-NEXT: [[TMP3:%.*]] = load float, ptr [[YY3]], align 4 +// CHECK-DDEFAULT-NEXT: [[ADD4:%.*]] = fadd reassoc float [[TMP2]], [[TMP3]] +// CHECK-DDEFAULT-NEXT: call void @_ZN9MyComplexC1Eff(ptr noundef nonnull align 4 dereferenceable(8) [[RETVAL]], float noundef [[ADD]], float noundef [[ADD4]]) +// CHECK-DDEFAULT-NEXT: [[TMP4:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4 +// CHECK-DDEFAULT-NEXT: ret <2 x float> [[TMP4]] +// +// CHECK-DEBSTRICT-LABEL: define linkonce_odr <2 x float> @_ZNK9MyComplexplES_ +// CHECK-DEBSTRICT-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]], <2 x float> [[OTHER_COERCE:%.*]]) #[[ATTR6:[0-9]+]] comdat align 2 { +// CHECK-DEBSTRICT-NEXT: entry: +// CHECK-DEBSTRICT-NEXT: [[RETVAL:%.*]] = alloca [[STRUCT_MYCOMPLEX:%.*]], align 4 +// CHECK-DEBSTRICT-NEXT: [[OTHER:%.*]] = alloca [[STRUCT_MYCOMPLEX]], align 4 +// CHECK-DEBSTRICT-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-DEBSTRICT-NEXT: store <2 x float> [[OTHER_COERCE]], ptr [[OTHER]], align 4 +// CHECK-DEBSTRICT-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 +// CHECK-DEBSTRICT-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// CHECK-DEBSTRICT-NEXT: [[XX:%.*]] = getelementptr inbounds [[STRUCT_MYCOMPLEX]], ptr [[THIS1]], i32 0, i32 0 +// CHECK-DEBSTRICT-NEXT: [[TMP0:%.*]] = load float, ptr [[XX]], align 4 +// CHECK-DEBSTRICT-NEXT: [[XX2:%.*]] = getelementptr inbounds [[STRUCT_MYCOMPLEX]], ptr [[OTHER]], i32 0, i32 0 +// CHECK-DEBSTRICT-NEXT: [[TMP1:%.*]] = load float, ptr [[XX2]], align 4 +// CHECK-DEBSTRICT-NEXT: [[ADD:%.*]] = fadd reassoc float [[TMP0]], [[TMP1]] +// CHECK-DEBSTRICT-NEXT: [[YY:%.*]] = getelementptr inbounds [[STRUCT_MYCOMPLEX]], ptr [[THIS1]], i32 0, i32 1 +// CHECK-DEBSTRICT-NEXT: [[TMP2:%.*]] = load float, ptr [[YY]], align 4 +// CHECK-DEBSTRICT-NEXT: [[YY3:%.*]] = getelementptr inbounds [[STRUCT_MYCOMPLEX]], ptr [[OTHER]], i32 0, i32 1 +// CHECK-DEBSTRICT-NEXT: [[TMP3:%.*]] = load float, ptr [[YY3]], align 4 +// CHECK-DEBSTRICT-NEXT: [[ADD4:%.*]] = fadd reassoc float [[TMP2]], [[TMP3]] +// CHECK-DEBSTRICT-NEXT: call void @_ZN9MyComplexC1Eff(ptr noundef nonnull align 4 dereferenceable(8) [[RETVAL]], float noundef [[ADD]], float noundef [[ADD4]]) +// CHECK-DEBSTRICT-NEXT: [[TMP4:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4 +// CHECK-DEBSTRICT-NEXT: ret <2 x float> [[TMP4]] +// +// CHECK-FAST-LABEL: define linkonce_odr <2 x float> @_ZNK9MyComplexplES_ +// CHECK-FAST-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]], <2 x float> [[OTHER_COERCE:%.*]]) #[[ATTR4:[0-9]+]] comdat align 2 { +// CHECK-FAST-NEXT: entry: +// CHECK-FAST-NEXT: [[RETVAL:%.*]] = alloca [[STRUCT_MYCOMPLEX:%.*]], align 4 +// CHECK-FAST-NEXT: [[OTHER:%.*]] = alloca [[STRUCT_MYCOMPLEX]], align 4 +// CHECK-FAST-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-FAST-NEXT: store <2 x float> [[OTHER_COERCE]], ptr [[OTHER]], align 4 +// CHECK-FAST-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 +// CHECK-FAST-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// CHECK-FAST-NEXT: [[XX:%.*]] = getelementptr inbounds [[STRUCT_MYCOMPLEX]], ptr [[THIS1]], i32 0, i32 0 +// CHECK-FAST-NEXT: [[TMP0:%.*]] = load float, ptr [[XX]], align 4 +// CHECK-FAST-NEXT: [[XX2:%.*]] = getelementptr inbounds [[STRUCT_MYCOMPLEX]], ptr [[OTHER]], i32 0, i32 0 +// CHECK-FAST-NEXT: [[TMP1:%.*]] = load float, ptr [[XX2]], align 4 +// CHECK-FAST-NEXT: [[ADD:%.*]] = fadd reassoc float [[TMP0]], [[TMP1]] +// CHECK-FAST-NEXT: [[YY:%.*]] = getelementptr inbounds [[STRUCT_MYCOMPLEX]], ptr [[THIS1]], i32 0, i32 1 +// CHECK-FAST-NEXT: [[TMP2:%.*]] = load float, ptr [[YY]], align 4 +// CHECK-FAST-NEXT: [[YY3:%.*]] = getelementptr inbounds [[STRUCT_MYCOMPLEX]], ptr [[OTHER]], i32 0, i32 1 +// CHECK-FAST-NEXT: [[TMP3:%.*]] = load float, ptr [[YY3]], align 4 +// CHECK-FAST-NEXT: [[ADD4:%.*]] = fadd reassoc float [[TMP2]], [[TMP3]] +// CHECK-FAST-NEXT: call void @_ZN9MyComplexC1Eff(ptr noundef nonnull align 4 dereferenceable(8) [[RETVAL]], float noundef nofpclass(nan inf) [[ADD]], float noundef nofpclass(nan inf) [[ADD4]]) +// CHECK-FAST-NEXT: [[TMP4:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4 +// CHECK-FAST-NEXT: ret <2 x float> [[TMP4]] +// +// CHECK-NOHONOR-LABEL: define linkonce_odr <2 x float> @_ZNK9MyComplexplES_ +// CHECK-NOHONOR-SAME: (ptr noundef nonnull align 4 dereferenceable(8) [[THIS:%.*]], <2 x float> [[OTHER_COERCE:%.*]]) #[[ATTR8:[0-9]+]] comdat align 2 { +// CHECK-NOHONOR-NEXT: entry: +// CHECK-NOHONOR-NEXT: [[RETVAL:%.*]] = alloca [[STRUCT_MYCOMPLEX:%.*]], align 4 +// CHECK-NOHONOR-NEXT: [[OTHER:%.*]] = alloca [[STRUCT_MYCOMPLEX]], align 4 +// CHECK-NOHONOR-NEXT: [[THIS_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NOHONOR-NEXT: store <2 x float> [[OTHER_COERCE]], ptr [[OTHER]], align 4 +// CHECK-NOHONOR-NEXT: store ptr [[THIS]], ptr [[THIS_ADDR]], align 8 +// CHECK-NOHONOR-NEXT: [[THIS1:%.*]] = load ptr, ptr [[THIS_ADDR]], align 8 +// CHECK-NOHONOR-NEXT: [[XX:%.*]] = getelementptr inbounds [[STRUCT_MYCOMPLEX]], ptr [[THIS1]], i32 0, i32 0 +// CHECK-NOHONOR-NEXT: [[TMP0:%.*]] = load float, ptr [[XX]], align 4 +// CHECK-NOHONOR-NEXT: [[XX2:%.*]] = getelementptr inbounds [[STRUCT_MYCOMPLEX]], ptr [[OTHER]], i32 0, i32 0 +// CHECK-NOHONOR-NEXT: [[TMP1:%.*]] = load float, ptr [[XX2]], align 4 +// CHECK-NOHONOR-NEXT: [[ADD:%.*]] = fadd reassoc float [[TMP0]], [[TMP1]] +// CHECK-NOHONOR-NEXT: [[YY:%.*]] = getelementptr inbounds [[STRUCT_MYCOMPLEX]], ptr [[THIS1]], i32 0, i32 1 +// CHECK-NOHONOR-NEXT: [[TMP2:%.*]] = load float, ptr [[YY]], align 4 +// CHECK-NOHONOR-NEXT: [[YY3:%.*]] = getelementptr inbounds [[STRUCT_MYCOMPLEX]], ptr [[OTHER]], i32 0, i32 1 +// CHECK-NOHONOR-NEXT: [[TMP3:%.*]] = load float, ptr [[YY3]], align 4 +// CHECK-NOHONOR-NEXT: [[ADD4:%.*]] = fadd reassoc float [[TMP2]], [[TMP3]] +// CHECK-NOHONOR-NEXT: call void @_ZN9MyComplexC1Eff(ptr noundef nonnull align 4 dereferenceable(8) [[RETVAL]], float noundef nofpclass(nan inf) [[ADD]], float noundef nofpclass(nan inf) [[ADD4]]) +// CHECK-NOHONOR-NEXT: [[TMP4:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4 +// CHECK-NOHONOR-NEXT: ret <2 x float> [[TMP4]] +// const MyComplex operator+(const MyComplex other) const { // CHECK-LABEL: define {{.*}} @_ZNK9MyComplexplES_ // CHECK: fadd reassoc float @@ -273,14 +859,74 @@ return MyComplex(xx + other.xx, yy + other.yy); } }; +// CHECK-DDEFAULT-LABEL: define dso_local <2 x float> @_Z6useAddv +// CHECK-DDEFAULT-SAME: () #[[ATTR6]] { +// CHECK-DDEFAULT-NEXT: entry: +// CHECK-DDEFAULT-NEXT: [[RETVAL:%.*]] = alloca [[STRUCT_MYCOMPLEX:%.*]], align 4 +// CHECK-DDEFAULT-NEXT: [[A:%.*]] = alloca [[STRUCT_MYCOMPLEX]], align 4 +// CHECK-DDEFAULT-NEXT: [[B:%.*]] = alloca [[STRUCT_MYCOMPLEX]], align 4 +// CHECK-DDEFAULT-NEXT: [[AGG_TMP:%.*]] = alloca [[STRUCT_MYCOMPLEX]], align 4 +// CHECK-DDEFAULT-NEXT: call void @_ZN9MyComplexC1Eff(ptr noundef nonnull align 4 dereferenceable(8) [[A]], float noundef 1.000000e+00, float noundef 3.000000e+00) +// CHECK-DDEFAULT-NEXT: call void @_ZN9MyComplexC1Eff(ptr noundef nonnull align 4 dereferenceable(8) [[B]], float noundef 2.000000e+00, float noundef 4.000000e+00) +// CHECK-DDEFAULT-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[AGG_TMP]], ptr align 4 [[B]], i64 8, i1 false) +// CHECK-DDEFAULT-NEXT: [[TMP0:%.*]] = load <2 x float>, ptr [[AGG_TMP]], align 4 +// CHECK-DDEFAULT-NEXT: [[CALL:%.*]] = call <2 x float> @_ZNK9MyComplexplES_(ptr noundef nonnull align 4 dereferenceable(8) [[A]], <2 x float> [[TMP0]]) +// CHECK-DDEFAULT-NEXT: store <2 x float> [[CALL]], ptr [[RETVAL]], align 4 +// CHECK-DDEFAULT-NEXT: [[TMP1:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4 +// CHECK-DDEFAULT-NEXT: ret <2 x float> [[TMP1]] +// +// CHECK-DEBSTRICT-LABEL: define dso_local <2 x float> @_Z6useAddv +// CHECK-DEBSTRICT-SAME: () #[[ATTR6]] { +// CHECK-DEBSTRICT-NEXT: entry: +// CHECK-DEBSTRICT-NEXT: [[RETVAL:%.*]] = alloca [[STRUCT_MYCOMPLEX:%.*]], align 4 +// CHECK-DEBSTRICT-NEXT: [[A:%.*]] = alloca [[STRUCT_MYCOMPLEX]], align 4 +// CHECK-DEBSTRICT-NEXT: [[B:%.*]] = alloca [[STRUCT_MYCOMPLEX]], align 4 +// CHECK-DEBSTRICT-NEXT: [[AGG_TMP:%.*]] = alloca [[STRUCT_MYCOMPLEX]], align 4 +// CHECK-DEBSTRICT-NEXT: call void @_ZN9MyComplexC1Eff(ptr noundef nonnull align 4 dereferenceable(8) [[A]], float noundef 1.000000e+00, float noundef 3.000000e+00) +// CHECK-DEBSTRICT-NEXT: call void @_ZN9MyComplexC1Eff(ptr noundef nonnull align 4 dereferenceable(8) [[B]], float noundef 2.000000e+00, float noundef 4.000000e+00) +// CHECK-DEBSTRICT-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[AGG_TMP]], ptr align 4 [[B]], i64 8, i1 false) +// CHECK-DEBSTRICT-NEXT: [[TMP0:%.*]] = load <2 x float>, ptr [[AGG_TMP]], align 4 +// CHECK-DEBSTRICT-NEXT: [[CALL:%.*]] = call <2 x float> @_ZNK9MyComplexplES_(ptr noundef nonnull align 4 dereferenceable(8) [[A]], <2 x float> [[TMP0]]) +// CHECK-DEBSTRICT-NEXT: store <2 x float> [[CALL]], ptr [[RETVAL]], align 4 +// CHECK-DEBSTRICT-NEXT: [[TMP1:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4 +// CHECK-DEBSTRICT-NEXT: ret <2 x float> [[TMP1]] +// +// CHECK-FAST-LABEL: define dso_local <2 x float> @_Z6useAddv +// CHECK-FAST-SAME: () #[[ATTR4]] { +// CHECK-FAST-NEXT: entry: +// CHECK-FAST-NEXT: [[RETVAL:%.*]] = alloca [[STRUCT_MYCOMPLEX:%.*]], align 4 +// CHECK-FAST-NEXT: [[A:%.*]] = alloca [[STRUCT_MYCOMPLEX]], align 4 +// CHECK-FAST-NEXT: [[B:%.*]] = alloca [[STRUCT_MYCOMPLEX]], align 4 +// CHECK-FAST-NEXT: [[AGG_TMP:%.*]] = alloca [[STRUCT_MYCOMPLEX]], align 4 +// CHECK-FAST-NEXT: call void @_ZN9MyComplexC1Eff(ptr noundef nonnull align 4 dereferenceable(8) [[A]], float noundef nofpclass(nan inf) 1.000000e+00, float noundef nofpclass(nan inf) 3.000000e+00) +// CHECK-FAST-NEXT: call void @_ZN9MyComplexC1Eff(ptr noundef nonnull align 4 dereferenceable(8) [[B]], float noundef nofpclass(nan inf) 2.000000e+00, float noundef nofpclass(nan inf) 4.000000e+00) +// CHECK-FAST-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[AGG_TMP]], ptr align 4 [[B]], i64 8, i1 false) +// CHECK-FAST-NEXT: [[TMP0:%.*]] = load <2 x float>, ptr [[AGG_TMP]], align 4 +// CHECK-FAST-NEXT: [[CALL:%.*]] = call fast <2 x float> @_ZNK9MyComplexplES_(ptr noundef nonnull align 4 dereferenceable(8) [[A]], <2 x float> [[TMP0]]) +// CHECK-FAST-NEXT: store <2 x float> [[CALL]], ptr [[RETVAL]], align 4 +// CHECK-FAST-NEXT: [[TMP1:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4 +// CHECK-FAST-NEXT: ret <2 x float> [[TMP1]] +// +// CHECK-NOHONOR-LABEL: define dso_local <2 x float> @_Z6useAddv +// CHECK-NOHONOR-SAME: () #[[ATTR8]] { +// CHECK-NOHONOR-NEXT: entry: +// CHECK-NOHONOR-NEXT: [[RETVAL:%.*]] = alloca [[STRUCT_MYCOMPLEX:%.*]], align 4 +// CHECK-NOHONOR-NEXT: [[A:%.*]] = alloca [[STRUCT_MYCOMPLEX]], align 4 +// CHECK-NOHONOR-NEXT: [[B:%.*]] = alloca [[STRUCT_MYCOMPLEX]], align 4 +// CHECK-NOHONOR-NEXT: [[AGG_TMP:%.*]] = alloca [[STRUCT_MYCOMPLEX]], align 4 +// CHECK-NOHONOR-NEXT: call void @_ZN9MyComplexC1Eff(ptr noundef nonnull align 4 dereferenceable(8) [[A]], float noundef nofpclass(nan inf) 1.000000e+00, float noundef nofpclass(nan inf) 3.000000e+00) +// CHECK-NOHONOR-NEXT: call void @_ZN9MyComplexC1Eff(ptr noundef nonnull align 4 dereferenceable(8) [[B]], float noundef nofpclass(nan inf) 2.000000e+00, float noundef nofpclass(nan inf) 4.000000e+00) +// CHECK-NOHONOR-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[AGG_TMP]], ptr align 4 [[B]], i64 8, i1 false) +// CHECK-NOHONOR-NEXT: [[TMP0:%.*]] = load <2 x float>, ptr [[AGG_TMP]], align 4 +// CHECK-NOHONOR-NEXT: [[CALL:%.*]] = call nnan ninf <2 x float> @_ZNK9MyComplexplES_(ptr noundef nonnull align 4 dereferenceable(8) [[A]], <2 x float> [[TMP0]]) +// CHECK-NOHONOR-NEXT: store <2 x float> [[CALL]], ptr [[RETVAL]], align 4 +// CHECK-NOHONOR-NEXT: [[TMP1:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4 +// CHECK-NOHONOR-NEXT: ret <2 x float> [[TMP1]] +// MyComplex useAdd() { MyComplex a (1, 3); MyComplex b (2, 4); return a + b; } -// CHECK-DDEFAULT: Function Attrs: noinline nounwind{{$$}} -// CHECK-DEBSTRICT: Function Attrs: noinline nounwind strictfp{{$$}} -// CHECK-FAST: Function Attrs: noinline nounwind{{$$}} -// CHECK-NOHONOR: Function Attrs: noinline nounwind{{$$}} // CHECK-LABEL: define{{.*}} @_GLOBAL__sub_I_fp_floatcontrol_stack diff --git a/clang/test/CodeGenOpenCL/cl20-device-side-enqueue-attributes.cl b/clang/test/CodeGenOpenCL/cl20-device-side-enqueue-attributes.cl --- a/clang/test/CodeGenOpenCL/cl20-device-side-enqueue-attributes.cl +++ b/clang/test/CodeGenOpenCL/cl20-device-side-enqueue-attributes.cl @@ -1,6 +1,6 @@ // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals --include-generated-funcs -// RUN: %clang_cc1 -fno-ident -no-enable-noundef-analysis %s -cl-std=CL2.0 -ffake-address-space-map -O0 -emit-llvm -o - -triple "spir-unknown-unknown" -fdenormal-fp-math-f32=preserve-sign -cl-uniform-work-group-size | FileCheck --check-prefix=SPIR32 %s -// RUN: %clang_cc1 -fno-ident -ffp-exception-behavior=strict -fexperimental-strict-floating-point -no-enable-noundef-analysis %s -cl-std=CL2.0 -ffake-address-space-map -O0 -emit-llvm -o - -triple "spir-unknown-unknown" | FileCheck --check-prefix=STRICTFP %s +// RUN: %clang_cc1 -fno-ident -no-enable-noundef-analysis %s -cl-std=CL2.0 -ffake-address-space-map -O0 -emit-llvm -o - -triple "spir-unknown-unknown" -fdenormal-fp-math-f32=preserve-sign -cl-uniform-work-group-size -target-feature +fma | FileCheck --check-prefix=SPIR32 %s +// RUN: %clang_cc1 -fno-ident -ffp-exception-behavior=strict -fexperimental-strict-floating-point -no-enable-noundef-analysis %s -cl-std=CL2.0 -ffake-address-space-map -O0 -emit-llvm -o - -triple "spir-unknown-unknown" -target-feature +fma | FileCheck --check-prefix=STRICTFP %s // Test that attributes are correctly applied to functions introduced for @@ -162,17 +162,17 @@ // STRICTFP-NEXT: ret void // //. -// SPIR32: attributes #0 = { convergent noinline norecurse nounwind optnone "denormal-fp-math-f32"="preserve-sign,preserve-sign" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "uniform-work-group-size"="true" } +// SPIR32: attributes #0 = { convergent noinline norecurse nounwind optnone "denormal-fp-math-f32"="preserve-sign,preserve-sign" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fma" "uniform-work-group-size"="true" } // SPIR32: attributes #1 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) } -// SPIR32: attributes #2 = { convergent noinline nounwind optnone "denormal-fp-math-f32"="preserve-sign,preserve-sign" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +// SPIR32: attributes #2 = { convergent noinline nounwind optnone "denormal-fp-math-f32"="preserve-sign,preserve-sign" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fma" } // SPIR32: attributes #3 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } -// SPIR32: attributes #4 = { convergent nounwind "denormal-fp-math-f32"="preserve-sign,preserve-sign" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +// SPIR32: attributes #4 = { convergent nounwind "denormal-fp-math-f32"="preserve-sign,preserve-sign" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fma" } //. -// STRICTFP: attributes #0 = { convergent noinline norecurse nounwind optnone strictfp "stack-protector-buffer-size"="8" "strictfp" "uniform-work-group-size"="false" } +// STRICTFP: attributes #0 = { convergent noinline norecurse nounwind optnone strictfp "stack-protector-buffer-size"="8" "strictfp" "target-features"="+fma" "uniform-work-group-size"="false" } // STRICTFP: attributes #1 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) } -// STRICTFP: attributes #2 = { convergent noinline nounwind optnone strictfp "stack-protector-buffer-size"="8" } +// STRICTFP: attributes #2 = { convergent noinline nounwind optnone strictfp "stack-protector-buffer-size"="8" "target-features"="+fma" } // STRICTFP: attributes #3 = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) } -// STRICTFP: attributes #4 = { convergent nounwind "stack-protector-buffer-size"="8" } +// STRICTFP: attributes #4 = { convergent nounwind "stack-protector-buffer-size"="8" "target-features"="+fma" } // STRICTFP: attributes #5 = { strictfp } //. // SPIR32: !0 = !{i32 1, !"wchar_size", i32 4} diff --git a/clang/test/CodeGenOpenCL/single-precision-constant.cl b/clang/test/CodeGenOpenCL/single-precision-constant.cl --- a/clang/test/CodeGenOpenCL/single-precision-constant.cl +++ b/clang/test/CodeGenOpenCL/single-precision-constant.cl @@ -1,6 +1,12 @@ -// RUN: %clang_cc1 %s -cl-single-precision-constant -emit-llvm -o - | FileCheck %s +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 +// RUN: %clang_cc1 %s -cl-single-precision-constant -emit-llvm -target-feature +fma -o - | FileCheck %s +// CHECK-LABEL: define dso_local float @fn +// CHECK-SAME: (float noundef [[F:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[TMP0:%.*]] = tail call float @llvm.fmuladd.f32(float [[F]], float 2.000000e+00, float 1.000000e+00) +// CHECK-NEXT: ret float [[TMP0]] +// float fn(float f) { - // CHECK: tail call float @llvm.fmuladd.f32(float %f, float 2.000000e+00, float 1.000000e+00) return f*2. + 1.; } diff --git a/clang/test/PCH/pragma-floatcontrol.c b/clang/test/PCH/pragma-floatcontrol.c --- a/clang/test/PCH/pragma-floatcontrol.c +++ b/clang/test/PCH/pragma-floatcontrol.c @@ -1,3 +1,4 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 // Test this without pch. // RUN: %clang_cc1 -fexperimental-strict-floating-point %s -include %s -verify -fsyntax-only -DSET // RUN: %clang_cc1 -fexperimental-strict-floating-point %s -include %s -verify -fsyntax-only -DPUSH @@ -44,11 +45,36 @@ #else #ifdef SET +// CHECK-EBSTRICT-LABEL: define dso_local float @fun +// CHECK-EBSTRICT-SAME: (float noundef [[A:%.*]], float noundef [[B:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-EBSTRICT-NEXT: entry: +// CHECK-EBSTRICT-NEXT: [[A_ADDR:%.*]] = alloca float, align 4 +// CHECK-EBSTRICT-NEXT: [[B_ADDR:%.*]] = alloca float, align 4 +// CHECK-EBSTRICT-NEXT: store float [[A]], ptr [[A_ADDR]], align 4 +// CHECK-EBSTRICT-NEXT: store float [[B]], ptr [[B_ADDR]], align 4 +// CHECK-EBSTRICT-NEXT: [[TMP0:%.*]] = load float, ptr [[A_ADDR]], align 4 +// CHECK-EBSTRICT-NEXT: [[TMP1:%.*]] = load float, ptr [[B_ADDR]], align 4 +// CHECK-EBSTRICT-NEXT: [[MUL:%.*]] = call float @llvm.experimental.constrained.fmul.f32(float [[TMP0]], float [[TMP1]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2:[0-9]+]] +// CHECK-EBSTRICT-NEXT: [[CONV:%.*]] = call float @llvm.experimental.constrained.sitofp.f32.i32(i32 2, metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-EBSTRICT-NEXT: [[ADD:%.*]] = call float @llvm.experimental.constrained.fadd.f32(float [[MUL]], float [[CONV]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-EBSTRICT-NEXT: ret float [[ADD]] +// +// CHECK-CONTRACT-LABEL: define dso_local float @fun +// CHECK-CONTRACT-SAME: (float noundef [[A:%.*]], float noundef [[B:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-CONTRACT-NEXT: entry: +// CHECK-CONTRACT-NEXT: [[A_ADDR:%.*]] = alloca float, align 4 +// CHECK-CONTRACT-NEXT: [[B_ADDR:%.*]] = alloca float, align 4 +// CHECK-CONTRACT-NEXT: store float [[A]], ptr [[A_ADDR]], align 4 +// CHECK-CONTRACT-NEXT: store float [[B]], ptr [[B_ADDR]], align 4 +// CHECK-CONTRACT-NEXT: [[TMP0:%.*]] = load float, ptr [[A_ADDR]], align 4 +// CHECK-CONTRACT-NEXT: [[TMP1:%.*]] = load float, ptr [[B_ADDR]], align 4 +// CHECK-CONTRACT-NEXT: [[MUL:%.*]] = call float @llvm.experimental.constrained.fmul.f32(float [[TMP0]], float [[TMP1]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2:[0-9]+]] +// CHECK-CONTRACT-NEXT: [[CONV:%.*]] = call float @llvm.experimental.constrained.sitofp.f32.i32(i32 2, metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-CONTRACT-NEXT: [[ADD:%.*]] = call float @llvm.experimental.constrained.fadd.f32(float [[MUL]], float [[CONV]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR2]] +// CHECK-CONTRACT-NEXT: ret float [[ADD]] +// float fun(float a, float b) { // CHECK-LABEL: define float @fun{{.*}} - //CHECK-EBSTRICT: llvm.experimental.constrained.fmul{{.*}}tonearest{{.*}}strict - //CHECK-EBSTRICT: llvm.experimental.constrained.fadd{{.*}}tonearest{{.*}}strict - //CHECK-CONTRACT: llvm.experimental.constrained.fmuladd{{.*}}tonearest{{.*}}strict return a * b + 2; } #pragma float_control(pop) // expected-warning {{#pragma float_control(pop, ...) failed: stack empty}}