File: array_equals_memcmp_dyn.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 (51 lines) | stat: -rw-r--r-- 2,119 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
// Tests that dynamic array (in)equality is optimized to a memcmp call when valid.

// RUN: %ldc -c -output-ll -of=%t.ll %s && FileCheck %s --check-prefix=LLVM < %t.ll
// RUN: %ldc -c -output-s -O3 -of=%t.s  %s && FileCheck %s --check-prefix=ASM  < %t.s
// RUN: %ldc -O0 -run %s
// RUN: %ldc -O3 -run %s

module mod;

// LLVM-LABEL: define{{.*}} @{{.*}}static_dynamic
// ASM-LABEL: static_dynamic{{.*}}:
bool static_dynamic(const bool[4] a, bool[] b)
{
    // LLVM: call i32 @memcmp(

    // Also test that LLVM recognizes and optimizes-out the call to memcmp for 4 byte arrays:
    // ASM-NOT: {{(mem|b)cmp}}
    return a == b;
}

// LLVM-LABEL: define{{.*}} @{{.*}}inv_dynamic_dynamic
// ASM-LABEL: inv_dynamic_dynamic{{.*}}:
bool inv_dynamic_dynamic(bool[] a, const bool[] b)
{
    // The front-end turns this into a call to druntime template function `object.__equals!(const(bool), const(bool)).__equals(const(bool)[], const(bool)[])`
    // After optimization (inlining), it should boil down to a length check and a call to memcmp.
    // ASM: {{(mem|b)cmp}}
    return a != b;
}

// LLVM-LABEL: define{{.*}} @{{.*}}_D4core8internal5array8equality__T8__equals
// ASM-LABEL: _D4core8internal5array8equality__T8__equals{{.*}}:

// LLVM-LABEL: define{{.*}} @_Dmain
// ASM-LABEL: _Dmain:
void main()
{
    assert( static_dynamic([true, false, true, false], [true, false, true, false]));
    assert(!static_dynamic([true, false, true, false], [true, false, true, true]));
    assert(!static_dynamic([true, false, true, false], [true, false, true, false, true]));
    assert(!static_dynamic([true, false, true, false], [true, false, true]));

    assert(!inv_dynamic_dynamic([true, false, true, false], [true, false, true, false]));
    assert( inv_dynamic_dynamic([true, false, true, false], [true, false, true, true]));
    assert( inv_dynamic_dynamic([true, false], [true]));
    assert( inv_dynamic_dynamic([true, false, true, false], [true, false, true]));

    // Make sure that comparing zero-length arrays with ptr=null is allowed.
    bool* ptr = null;
    assert(!inv_dynamic_dynamic(ptr[0..0], ptr[0..0]));
}