xref: /llvm-project/clang/test/Modules/pr93497.cppm (revision b0f10a1dc34aa1b73faeeabdc2d348074a02c75d)
1// RUN: rm -rf %t
2// RUN: mkdir -p %t
3// RUN: split-file %s %t
4
5// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 %t/mod.cppm \
6// RUN:     -emit-module-interface -o %t/mod.pcm
7// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 %t/use.cpp \
8// RUN:     -fmodule-file=mod=%t/mod.pcm -emit-llvm \
9// RUN:     -o - | opt -S --passes=simplifycfg | FileCheck %t/use.cpp
10
11//--- mod.cppm
12export module mod;
13
14export struct Thing {
15    static const Thing One;
16    explicit Thing(int raw) :raw(raw) { }
17    int raw;
18};
19
20const Thing Thing::One = Thing(1);
21
22export struct C {
23    int value;
24};
25export const C ConstantValue = {1};
26
27export const C *ConstantPtr = &ConstantValue;
28
29C NonConstantValue = {1};
30export const C &ConstantRef = NonConstantValue;
31
32export struct NonConstexprDtor {
33    constexpr NonConstexprDtor(int raw) : raw(raw) {}
34    ~NonConstexprDtor();
35
36    int raw;
37};
38
39export const NonConstexprDtor NonConstexprDtorValue = {1};
40
41//--- use.cpp
42import mod;
43
44int consume(int);
45int consumeC(C);
46
47extern "C" __attribute__((noinline)) inline int unneeded() {
48    return consume(43);
49}
50
51extern "C" __attribute__((noinline)) inline int needed() {
52    return consume(43);
53}
54
55int use() {
56    Thing t1 = Thing::One;
57    return consume(t1.raw);
58}
59
60int use2() {
61    if (ConstantValue.value)
62        return consumeC(ConstantValue);
63    return unneeded();
64}
65
66int use3() {
67    auto Ptr = ConstantPtr;
68    if (Ptr->value)
69        return consumeC(*Ptr);
70    return needed();
71}
72
73int use4() {
74    auto Ref = ConstantRef;
75    if (Ref.value)
76        return consumeC(Ref);
77    return needed();
78}
79
80int use5() {
81    NonConstexprDtor V = NonConstexprDtorValue;
82    if (V.raw)
83        return consume(V.raw);
84    return needed();
85}
86
87// CHECK: @_ZNW3mod5Thing3OneE = external
88// CHECK: @_ZW3mod13ConstantValue ={{.*}}available_externally{{.*}} constant
89// CHECK: @_ZW3mod11ConstantPtr = external
90// CHECK: @_ZW3mod16NonConstantValue = external
91// CHECK: @_ZW3mod21NonConstexprDtorValue = external
92
93// Check that the middle end can optimize the program by the constant information.
94// CHECK-NOT: @unneeded(
95
96// Check that the use of ConstantPtr won't get optimized incorrectly.
97// CHECK-LABEL: @_Z4use3v(
98// CHECK: @needed(
99
100// Check that the use of ConstantRef won't get optimized incorrectly.
101// CHECK-LABEL: @_Z4use4v(
102// CHECK: @needed(
103
104// Check that the use of NonConstexprDtorValue won't get optimized incorrectly.
105// CHECK-LABEL: @_Z4use5v(
106// CHECK: @needed(
107