Chuanqi Xu b0f10a1dc3
[C++20] [Modules] Don't generate the defintition for non-const available external variables (#93530)
Close https://github.com/llvm/llvm-project/issues/93497

The root cause of the problem is, we mark the variable from other
modules as constnant in LLVM incorrectly. This patch fixes this problem
by not emitting the defintition for non-const available external
variables. Since the non const available externally variable is not
helpful to the optimization.
2024-05-29 13:39:57 +08:00

107 lines
2.4 KiB
C++

// RUN: rm -rf %t
// RUN: mkdir -p %t
// RUN: split-file %s %t
// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 %t/mod.cppm \
// RUN: -emit-module-interface -o %t/mod.pcm
// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 %t/use.cpp \
// RUN: -fmodule-file=mod=%t/mod.pcm -emit-llvm \
// RUN: -o - | opt -S --passes=simplifycfg | FileCheck %t/use.cpp
//--- mod.cppm
export module mod;
export struct Thing {
static const Thing One;
explicit Thing(int raw) :raw(raw) { }
int raw;
};
const Thing Thing::One = Thing(1);
export struct C {
int value;
};
export const C ConstantValue = {1};
export const C *ConstantPtr = &ConstantValue;
C NonConstantValue = {1};
export const C &ConstantRef = NonConstantValue;
export struct NonConstexprDtor {
constexpr NonConstexprDtor(int raw) : raw(raw) {}
~NonConstexprDtor();
int raw;
};
export const NonConstexprDtor NonConstexprDtorValue = {1};
//--- use.cpp
import mod;
int consume(int);
int consumeC(C);
extern "C" __attribute__((noinline)) inline int unneeded() {
return consume(43);
}
extern "C" __attribute__((noinline)) inline int needed() {
return consume(43);
}
int use() {
Thing t1 = Thing::One;
return consume(t1.raw);
}
int use2() {
if (ConstantValue.value)
return consumeC(ConstantValue);
return unneeded();
}
int use3() {
auto Ptr = ConstantPtr;
if (Ptr->value)
return consumeC(*Ptr);
return needed();
}
int use4() {
auto Ref = ConstantRef;
if (Ref.value)
return consumeC(Ref);
return needed();
}
int use5() {
NonConstexprDtor V = NonConstexprDtorValue;
if (V.raw)
return consume(V.raw);
return needed();
}
// CHECK: @_ZNW3mod5Thing3OneE = external
// CHECK: @_ZW3mod13ConstantValue ={{.*}}available_externally{{.*}} constant
// CHECK: @_ZW3mod11ConstantPtr = external
// CHECK: @_ZW3mod16NonConstantValue = external
// CHECK: @_ZW3mod21NonConstexprDtorValue = external
// Check that the middle end can optimize the program by the constant information.
// CHECK-NOT: @unneeded(
// Check that the use of ConstantPtr won't get optimized incorrectly.
// CHECK-LABEL: @_Z4use3v(
// CHECK: @needed(
// Check that the use of ConstantRef won't get optimized incorrectly.
// CHECK-LABEL: @_Z4use4v(
// CHECK: @needed(
// Check that the use of NonConstexprDtorValue won't get optimized incorrectly.
// CHECK-LABEL: @_Z4use5v(
// CHECK: @needed(