File: inlineIR_math.d

package info (click to toggle)
ldc 1%3A1.40.0-5
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 63,308 kB
  • sloc: cpp: 85,368; ansic: 21,877; makefile: 1,705; sh: 1,018; asm: 584; objc: 135; exp: 48; python: 12
file content (120 lines) | stat: -rw-r--r-- 3,489 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// Tests inline IR + math optimizations

// REQUIRES: target_X86

// RUN: %ldc -c -output-ll -of=%t.ll %s && FileCheck %s --check-prefix LLVM < %t.ll
// RUN: %ldc -mtriple=x86_64-linux-gnu -mattr=+fma -O3 -release -c -output-s -of=%t.s %s && FileCheck %s --check-prefix ASM < %t.s

import ldc.attributes;
import ldc.llvmasm;

// Test that internal @inline.ir.*" functions for the inlined IR pieces are always inlined and are not present as a global symbol
// LLVM-NOT: @inline.ir.
// LLVM-NOT: alwaysinline


// __ir should inherit the enclosing function attributes, thus preserving the enclosing function attributes after inlining.
// LLVM-LABEL: define{{.*}} @dot
// LLVM-SAME: #[[UNSAFEFPMATH:[0-9]+]]
// ASM-LABEL: dot:
@llvmAttr("unsafe-fp-math", "true")
extern (C) double dot(double[] a, double[] b)
{
    double s = 0;

// ASM: vfmadd{{[123][123][123]}}pd
    foreach (size_t i; 0 .. a.length)
    {
        s = __ir!(`%p = fmul fast double %0, %1
                   %r = fadd fast double %p, %2
                   ret double %r`, double)(a[i], b[i], s);
    }
    return s;
}

// LLVM-LABEL: define{{.*}} @features
// LLVM-SAME: #[[FEAT:[0-9]+]]
@target("fma")
extern (C) double features(double[] a, double[] b)
{
    double s = 0;
    foreach (size_t i; 0 .. a.length)
    {
        s = __ir!(`%p = fmul fast double %0, %1
                   %r = fadd fast double %p, %2
                   ret double %r`, double)(a[i], b[i], s);
    }
    return s;
}

// Test that inline IR works when calling function has special attributes defined for its parameters
// LLVM-LABEL: define{{.*}} @dot160
// ASM-LABEL: dot160:
extern (C) double dot160(double[160] a, double[160] b)
{
    double s = 0;

// ASM-NOT: vfmadd
    foreach (size_t i; 0 .. a.length)
    {
        s = __ir!(`%p = fmul double %0, %1
                   %r = fadd double %p, %2
                   ret double %r`, double)(a[i], b[i], s);
    }
    return s;
}

// Test inline IR alias defined outside any function
alias __ir!(`%p = fmul fast double %0, %1
             %r = fadd fast double %p, %2
             ret double %r`,
             double, double, double, double) muladdFast;
alias __ir!(`%p = fmul double %0, %1
             %r = fadd double %p, %2
             ret double %r`,
             double, double, double, double) muladd;

// LLVM-LABEL: define{{.*}} @aliasInlineUnsafe
// LLVM-SAME: #[[UNSAFEFPMATH]]
// ASM-LABEL: aliasInlineUnsafe:
@llvmAttr("unsafe-fp-math", "true")
extern (C) double aliasInlineUnsafe(double[] a, double[] b)
{
    double s = 0;

// ASM: vfmadd{{[123][123][123]}}pd
    foreach (size_t i; 0 .. a.length)
    {
        s = muladdFast(a[i], b[i], s);
    }
    return s;
}

// LLVM-LABEL: define{{.*}} @aliasInlineSafe
// LLVM-SAME: #[[NO_UNSAFEFPMATH:[0-9]+]]
// ASM-LABEL: aliasInlineSafe:
extern (C) double aliasInlineSafe(double[] a, double[] b)
{
    double s = 0;

// ASM-NOT: vfmadd{{[123][123][123]}}pd
    foreach (size_t i; 0 .. a.length)
    {
        s = muladd(a[i], b[i], s);
    }
    return s;
}

// Make sure an enclosing function's 'noinline' attribute isn't copied to
// the inlined IR function (having 'alwaysinline') (issue #1711).
double neverInlinedEnclosingFunction()
{
    pragma(inline, false);
    return muladd(1.0, 2.0, 3.0);
}

// LLVM: attributes #[[UNSAFEFPMATH]] ={{.*}} "unsafe-fp-math"="true"
// LLVM: attributes #[[FEAT]] ={{.*}} "target-features"="{{.*}}+fma{{.*}}"

// LLVM: attributes #[[NO_UNSAFEFPMATH]] =
// LLVM-NOT: "unsafe-fp-math"="true"