Skip to content

Commit

Permalink
[CodeGenCXX] Treat 'this' as noalias in constructors
Browse files Browse the repository at this point in the history
This is currently a clang extension and a resolution
of the defect report in the C++ Standard.

Differential Revision: https://reviews.llvm.org/D46441

llvm-svn: 344150
  • Loading branch information
AntonBikineev committed Oct 10, 2018
1 parent 9efbfa8 commit cc7e747
Show file tree
Hide file tree
Showing 148 changed files with 875 additions and 859 deletions.
16 changes: 16 additions & 0 deletions clang/lib/CodeGen/CGCall.cpp
Expand Up @@ -2041,6 +2041,22 @@ void CodeGenModule::ConstructAttributeList(
Attrs.addAttribute(llvm::Attribute::Nest);
else if (AI.getInReg())
Attrs.addAttribute(llvm::Attribute::InReg);
if (ArgNo == 0 && TargetDecl && isa<CXXConstructorDecl>(TargetDecl)) {
// C++ [class.ctor]p14:
// During the construction of an object, if the value of the object
// or any of its subobjects is accessed through a glvalue that is not
// obtained, directly or indirectly, from the constructor’s this
// pointer, the value of the object or subobject thus obtained is
// unspecified.
//
// We intentionally treat this behaviour as undefined by marking 'this'
// with noalias attribute and have recommended the Standard to be
// changed accordingly.
unsigned ThisIRArg, NumIRArgs;
std::tie(ThisIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs(ArgNo);
assert((NumIRArgs == 1) && "unexpected IR mapping for 'this' argument");
Attrs.addAttribute(llvm::Attribute::NoAlias);
}
break;

case ABIArgInfo::Indirect: {
Expand Down
12 changes: 6 additions & 6 deletions clang/test/CXX/except/except.spec/p14-ir.cpp
Expand Up @@ -26,12 +26,12 @@ struct X4 {
struct X5 : X0, X4 { };

void test(X2 x2, X3 x3, X5 x5) {
// CHECK: define linkonce_odr void @_ZN2X2C1ERKS_(%struct.X2* %this, %struct.X2* dereferenceable({{[0-9]+}})) unnamed_addr
// CHECK: define linkonce_odr void @_ZN2X2C1ERKS_(%struct.X2* noalias %this, %struct.X2* dereferenceable({{[0-9]+}})) unnamed_addr
// CHECK: call void @_ZN2X2C2ERKS_({{.*}}) [[NUW:#[0-9]+]]
// CHECK-NEXT: ret void
// CHECK-NEXT: }
X2 x2a(x2);
// CHECK: define linkonce_odr void @_ZN2X3C1ERKS_(%struct.X3* %this, %struct.X3* dereferenceable({{[0-9]+}})) unnamed_addr
// CHECK: define linkonce_odr void @_ZN2X3C1ERKS_(%struct.X3* noalias %this, %struct.X3* dereferenceable({{[0-9]+}})) unnamed_addr
// CHECK: call void @_ZN2X3C2ERKS_({{.*}}) [[NUW]]
// CHECK-NEXT: ret void
// CHECK-NEXT: }
Expand All @@ -55,22 +55,22 @@ struct X8 : X6 { };
struct X9 : X6, X7 { };

void test() {
// CHECK: define linkonce_odr void @_ZN2X8C1Ev(%struct.X8* %this) unnamed_addr
// CHECK: define linkonce_odr void @_ZN2X8C1Ev(%struct.X8* noalias %this) unnamed_addr
// CHECK: call void @_ZN2X8C2Ev({{.*}}) [[NUW]]
// CHECK-NEXT: ret void
X8();

// CHECK: define linkonce_odr void @_ZN2X9C1Ev(%struct.X9* %this) unnamed_addr
// CHECK: define linkonce_odr void @_ZN2X9C1Ev(%struct.X9* noalias %this) unnamed_addr
// FIXME: check that this is the end of the line here:
// CHECK: call void @_ZN2X9C2Ev({{.*}})
// CHECK-NEXT: ret void
X9();

// CHECK: define linkonce_odr void @_ZN2X8C2Ev(%struct.X8* %this) unnamed_addr
// CHECK: define linkonce_odr void @_ZN2X8C2Ev(%struct.X8* noalias %this) unnamed_addr
// CHECK: call void @_ZN2X6C2Ev({{.*}}) [[NUW]]
// CHECK-NEXT: ret void

// CHECK: define linkonce_odr void @_ZN2X9C2Ev(%struct.X9* %this) unnamed_addr
// CHECK: define linkonce_odr void @_ZN2X9C2Ev(%struct.X9* noalias %this) unnamed_addr
// CHECK: call void @_ZN2X6C2Ev({{.*}}) [[NUW]]
// FIXME: and here:
// CHECK-NEXT: bitcast
Expand Down
16 changes: 8 additions & 8 deletions clang/test/CodeGen/temporary-lifetime.cpp
Expand Up @@ -22,24 +22,24 @@ T Baz();
void Test1() {
// CHECK-DTOR-LABEL: Test1
// CHECK-DTOR: call void @llvm.lifetime.start.p0i8(i64 1024, i8* nonnull %[[ADDR:[0-9]+]])
// CHECK-DTOR: call void @_ZN1AC1Ev(%struct.A* nonnull %[[VAR:[^ ]+]])
// CHECK-DTOR: call void @_ZN1AC1Ev(%struct.A* noalias nonnull %[[VAR:[^ ]+]])
// CHECK-DTOR: call void @_Z3FooIRK1AEvOT_
// CHECK-DTOR: call void @_ZN1AD1Ev(%struct.A* nonnull %[[VAR]])
// CHECK-DTOR: call void @llvm.lifetime.end.p0i8(i64 1024, i8* nonnull %[[ADDR]])
// CHECK-DTOR: call void @llvm.lifetime.start.p0i8(i64 1024, i8* nonnull %[[ADDR:[0-9]+]])
// CHECK-DTOR: call void @_ZN1AC1Ev(%struct.A* nonnull %[[VAR:[^ ]+]])
// CHECK-DTOR: call void @_ZN1AC1Ev(%struct.A* noalias nonnull %[[VAR:[^ ]+]])
// CHECK-DTOR: call void @_Z3FooIRK1AEvOT_
// CHECK-DTOR: call void @_ZN1AD1Ev(%struct.A* nonnull %[[VAR]])
// CHECK-DTOR: call void @llvm.lifetime.end.p0i8(i64 1024, i8* nonnull %[[ADDR]])
// CHECK-DTOR: }

// CHECK-NO-DTOR-LABEL: Test1
// CHECK-NO-DTOR: call void @llvm.lifetime.start.p0i8(i64 1024, i8* nonnull %[[ADDR:[0-9]+]])
// CHECK-NO-DTOR: call void @_ZN1AC1Ev(%struct.A* nonnull %[[VAR:[^ ]+]])
// CHECK-NO-DTOR: call void @_ZN1AC1Ev(%struct.A* noalias nonnull %[[VAR:[^ ]+]])
// CHECK-NO-DTOR: call void @_Z3FooIRK1AEvOT_
// CHECK-NO-DTOR: call void @llvm.lifetime.end.p0i8(i64 1024, i8* nonnull %[[ADDR]])
// CHECK-NO-DTOR: call void @llvm.lifetime.start.p0i8(i64 1024, i8* nonnull %[[ADDR:[0-9]+]])
// CHECK-NO-DTOR: call void @_ZN1AC1Ev(%struct.A* nonnull %[[VAR:[^ ]+]])
// CHECK-NO-DTOR: call void @_ZN1AC1Ev(%struct.A* noalias nonnull %[[VAR:[^ ]+]])
// CHECK-NO-DTOR: call void @_Z3FooIRK1AEvOT_
// CHECK-NO-DTOR: call void @llvm.lifetime.end.p0i8(i64 1024, i8* nonnull %[[ADDR]])
// CHECK-NO-DTOR: }
Expand All @@ -56,10 +56,10 @@ void Test1() {
void Test2() {
// CHECK-DTOR-LABEL: Test2
// CHECK-DTOR: call void @llvm.lifetime.start.p0i8(i64 1024, i8* nonnull %[[ADDR1:[0-9]+]])
// CHECK-DTOR: call void @_ZN1AC1Ev(%struct.A* nonnull %[[VAR1:[^ ]+]])
// CHECK-DTOR: call void @_ZN1AC1Ev(%struct.A* noalias nonnull %[[VAR1:[^ ]+]])
// CHECK-DTOR: call void @_Z3FooIRK1AEvOT_
// CHECK-DTOR: call void @llvm.lifetime.start.p0i8(i64 1024, i8* nonnull %[[ADDR2:[0-9]+]])
// CHECK-DTOR: call void @_ZN1AC1Ev(%struct.A* nonnull %[[VAR2:[^ ]+]])
// CHECK-DTOR: call void @_ZN1AC1Ev(%struct.A* noalias nonnull %[[VAR2:[^ ]+]])
// CHECK-DTOR: call void @_Z3FooIRK1AEvOT_
// CHECK-DTOR: call void @_ZN1AD1Ev(%struct.A* nonnull %[[VAR2]])
// CHECK-DTOR: call void @llvm.lifetime.end.p0i8(i64 1024, i8* nonnull %[[ADDR2]])
Expand All @@ -69,10 +69,10 @@ void Test2() {

// CHECK-NO-DTOR-LABEL: Test2
// CHECK-NO-DTOR: call void @llvm.lifetime.start.p0i8(i64 1024, i8* nonnull %[[ADDR1:[0-9]+]])
// CHECK-NO-DTOR: call void @_ZN1AC1Ev(%struct.A* nonnull %[[VAR1:[^ ]+]])
// CHECK-NO-DTOR: call void @_ZN1AC1Ev(%struct.A* noalias nonnull %[[VAR1:[^ ]+]])
// CHECK-NO-DTOR: call void @_Z3FooIRK1AEvOT_
// CHECK-NO-DTOR: call void @llvm.lifetime.start.p0i8(i64 1024, i8* nonnull %[[ADDR2:[0-9]+]])
// CHECK-NO-DTOR: call void @_ZN1AC1Ev(%struct.A* nonnull %[[VAR2:[^ ]+]])
// CHECK-NO-DTOR: call void @_ZN1AC1Ev(%struct.A* noalias nonnull %[[VAR2:[^ ]+]])
// CHECK-NO-DTOR: call void @_Z3FooIRK1AEvOT_
// CHECK-NO-DTOR: call void @llvm.lifetime.end.p0i8(i64 1024, i8* nonnull %[[ADDR2]])
// CHECK-NO-DTOR: call void @llvm.lifetime.end.p0i8(i64 1024, i8* nonnull %[[ADDR1]])
Expand Down
36 changes: 18 additions & 18 deletions clang/test/CodeGenCUDA/device-var-init.cu
Expand Up @@ -173,59 +173,59 @@ __device__ void df() {
T t;
// CHECK-NOT: call
EC ec;
// CHECK: call void @_ZN2ECC1Ev(%struct.EC* %[[ec]])
// CHECK: call void @_ZN2ECC1Ev(%struct.EC* noalias %[[ec]])
ED ed;
// CHECK-NOT: call
ECD ecd;
// CHECK: call void @_ZN3ECDC1Ev(%struct.ECD* %[[ecd]])
// CHECK: call void @_ZN3ECDC1Ev(%struct.ECD* noalias %[[ecd]])
ETC etc;
// CHECK: call void @_ZN3ETCC1IJEEEDpT_(%struct.ETC* %[[etc]])
// CHECK: call void @_ZN3ETCC1IJEEEDpT_(%struct.ETC* noalias %[[etc]])
UC uc;
// undefined constructor -- not allowed
// CHECK: call void @_ZN2UCC1Ev(%struct.UC* %[[uc]])
// CHECK: call void @_ZN2UCC1Ev(%struct.UC* noalias %[[uc]])
UD ud;
// undefined destructor -- not allowed
// CHECK-NOT: call
ECI eci;
// empty constructor w/ initializer list -- not allowed
// CHECK: call void @_ZN3ECIC1Ev(%struct.ECI* %[[eci]])
// CHECK: call void @_ZN3ECIC1Ev(%struct.ECI* noalias %[[eci]])
NEC nec;
// non-empty constructor -- not allowed
// CHECK: call void @_ZN3NECC1Ev(%struct.NEC* %[[nec]])
// CHECK: call void @_ZN3NECC1Ev(%struct.NEC* noalias %[[nec]])
// non-empty destructor -- not allowed
NED ned;
// no-constructor, virtual method -- not allowed
// CHECK: call void @_ZN3NCVC1Ev(%struct.NCV* %[[ncv]])
// CHECK: call void @_ZN3NCVC1Ev(%struct.NCV* noalias %[[ncv]])
NCV ncv;
// CHECK-NOT: call
VD vd;
// CHECK: call void @_ZN2VDC1Ev(%struct.VD* %[[vd]])
// CHECK: call void @_ZN2VDC1Ev(%struct.VD* noalias %[[vd]])
NCF ncf;
// CHECK: call void @_ZN3NCFC1Ev(%struct.NCF* %[[ncf]])
// CHECK: call void @_ZN3NCFC1Ev(%struct.NCF* noalias %[[ncf]])
NCFS ncfs;
// CHECK: call void @_ZN4NCFSC1Ev(%struct.NCFS* %[[ncfs]])
// CHECK: call void @_ZN4NCFSC1Ev(%struct.NCFS* noalias %[[ncfs]])
UTC utc;
// CHECK: call void @_ZN3UTCC1IJEEEDpT_(%struct.UTC* %[[utc]])
// CHECK: call void @_ZN3UTCC1IJEEEDpT_(%struct.UTC* noalias %[[utc]])
NETC netc;
// CHECK: call void @_ZN4NETCC1IJEEEDpT_(%struct.NETC* %[[netc]])
// CHECK: call void @_ZN4NETCC1IJEEEDpT_(%struct.NETC* noalias %[[netc]])
T_B_T t_b_t;
// CHECK-NOT: call
T_F_T t_f_t;
// CHECK-NOT: call
T_FA_T t_fa_t;
// CHECK-NOT: call
EC_I_EC ec_i_ec;
// CHECK: call void @_ZN7EC_I_ECC1Ev(%struct.EC_I_EC* %[[ec_i_ec]])
// CHECK: call void @_ZN7EC_I_ECC1Ev(%struct.EC_I_EC* noalias %[[ec_i_ec]])
EC_I_EC1 ec_i_ec1;
// CHECK: call void @_ZN8EC_I_EC1C1Ev(%struct.EC_I_EC1* %[[ec_i_ec1]])
// CHECK: call void @_ZN8EC_I_EC1C1Ev(%struct.EC_I_EC1* noalias %[[ec_i_ec1]])
T_V_T t_v_t;
// CHECK: call void @_ZN5T_V_TC1Ev(%struct.T_V_T* %[[t_v_t]])
// CHECK: call void @_ZN5T_V_TC1Ev(%struct.T_V_T* noalias %[[t_v_t]])
T_B_NEC t_b_nec;
// CHECK: call void @_ZN7T_B_NECC1Ev(%struct.T_B_NEC* %[[t_b_nec]])
// CHECK: call void @_ZN7T_B_NECC1Ev(%struct.T_B_NEC* noalias %[[t_b_nec]])
T_F_NEC t_f_nec;
// CHECK: call void @_ZN7T_F_NECC1Ev(%struct.T_F_NEC* %[[t_f_nec]])
// CHECK: call void @_ZN7T_F_NECC1Ev(%struct.T_F_NEC* noalias %[[t_f_nec]])
T_FA_NEC t_fa_nec;
// CHECK: call void @_ZN8T_FA_NECC1Ev(%struct.T_FA_NEC* %[[t_fa_nec]])
// CHECK: call void @_ZN8T_FA_NECC1Ev(%struct.T_FA_NEC* noalias %[[t_fa_nec]])
T_B_NED t_b_ned;
// CHECK-NOT: call
T_F_NED t_f_ned;
Expand Down
6 changes: 3 additions & 3 deletions clang/test/CodeGenCXX/2011-12-19-init-list-ctor.cpp
Expand Up @@ -19,8 +19,8 @@ struct S {
};

// CHECK: store i32 0, i32* getelementptr inbounds ([3 x %struct.S], [3 x %struct.S]* @arr, i64 0, i64 0, i32 0)
// CHECK: call void @_ZN1AC1EPKc(%struct.A* getelementptr inbounds ([3 x %struct.S], [3 x %struct.S]* @arr, i64 0, i64 0, i32 1), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i32 0, i32 0))
// CHECK: call void @_ZN1AC1EPKc(%struct.A* noalias getelementptr inbounds ([3 x %struct.S], [3 x %struct.S]* @arr, i64 0, i64 0, i32 1), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i32 0, i32 0))
// CHECK: store i32 1, i32* getelementptr inbounds ([3 x %struct.S], [3 x %struct.S]* @arr, i64 0, i64 1, i32 0)
// CHECK: call void @_ZN1AC1EPKc(%struct.A* getelementptr inbounds ([3 x %struct.S], [3 x %struct.S]* @arr, i64 0, i64 1, i32 1), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0))
// CHECK: call void @_ZN1AC1EPKc(%struct.A* noalias getelementptr inbounds ([3 x %struct.S], [3 x %struct.S]* @arr, i64 0, i64 1, i32 1), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0))
// CHECK: store i32 2, i32* getelementptr inbounds ([3 x %struct.S], [3 x %struct.S]* @arr, i64 0, i64 2, i32 0)
// CHECK: call void @_ZN1AC1EPKc(%struct.A* getelementptr inbounds ([3 x %struct.S], [3 x %struct.S]* @arr, i64 0, i64 2, i32 1), i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str.2, i32 0, i32 0))
// CHECK: call void @_ZN1AC1EPKc(%struct.A* noalias getelementptr inbounds ([3 x %struct.S], [3 x %struct.S]* @arr, i64 0, i64 2, i32 1), i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str.2, i32 0, i32 0))
2 changes: 1 addition & 1 deletion clang/test/CodeGenCXX/amdgcn-automatic-variable.cpp
Expand Up @@ -67,7 +67,7 @@ int x;
void func3() {
// CHECK: %[[a:.*]] = alloca %class.A, align 4, addrspace(5)
// CHECK: %[[r0:.*]] = addrspacecast %class.A addrspace(5)* %[[a]] to %class.A*
// CHECK: call void @_ZN1AC1Ev(%class.A* %[[r0]])
// CHECK: call void @_ZN1AC1Ev(%class.A* noalias %[[r0]])
// CHECK: call void @_ZN1AD1Ev(%class.A* %[[r0]])
A a;
}
Expand Down
2 changes: 1 addition & 1 deletion clang/test/CodeGenCXX/amdgcn-func-arg.cpp
Expand Up @@ -31,7 +31,7 @@ void func_with_indirect_arg(A a) {
// CHECK: %[[r0:.+]] = addrspacecast %class.A addrspace(5)* %a to %class.A*
// CHECK: %agg.tmp = alloca %class.A, align 4, addrspace(5)
// CHECK: %[[r1:.+]] = addrspacecast %class.A addrspace(5)* %agg.tmp to %class.A*
// CHECK: call void @_ZN1AC1Ev(%class.A* %[[r0]])
// CHECK: call void @_ZN1AC1Ev(%class.A* noalias %[[r0]])
// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
// CHECK: %[[r4:.+]] = addrspacecast %class.A* %[[r1]] to %class.A addrspace(5)*
// CHECK: call void @_Z22func_with_indirect_arg1A(%class.A addrspace(5)* %[[r4]])
Expand Down
2 changes: 1 addition & 1 deletion clang/test/CodeGenCXX/apple-kext.cpp
Expand Up @@ -10,7 +10,7 @@ namespace test0 {
A a;
}
// CHECK: define internal void [[CTOR0_:@.*]]()
// CHECK: call void @_ZN5test01AC1Ev([[A]]* @_ZN5test01aE)
// CHECK: call void @_ZN5test01AC1Ev([[A]]* noalias @_ZN5test01aE)
// CHECK-NEXT: ret void

// CHECK: define internal void [[CTOR0]]()
Expand Down
6 changes: 3 additions & 3 deletions clang/test/CodeGenCXX/arm.cpp
Expand Up @@ -46,15 +46,15 @@ namespace test1 {
// CHECK-LABEL: define void @_ZN5test14testEv()
void test() {
// CHECK: [[AV:%.*]] = alloca [[A:%.*]], align 1
// CHECK: call [[A]]* @_ZN5test11AC1Ei([[A]]* [[AV]], i32 10)
// CHECK: call [[A]]* @_ZN5test11AC1Ei([[A]]* noalias [[AV]], i32 10)
// CHECK: invoke void @_ZN5test11A3barEv([[A]]* [[AV]])
// CHECK: call [[A]]* @_ZN5test11AD1Ev([[A]]* [[AV]])
// CHECK: ret void
A a = 10;
a.bar();
}

// CHECK: define linkonce_odr [[A]]* @_ZN5test11AC1Ei([[A]]* returned %this, i32 %i) unnamed_addr
// CHECK: define linkonce_odr [[A]]* @_ZN5test11AC1Ei([[A]]* noalias returned %this, i32 %i) unnamed_addr
// CHECK: [[THIS:%.*]] = alloca [[A]]*, align 4
// CHECK: store [[A]]* {{.*}}, [[A]]** [[THIS]]
// CHECK: [[THIS1:%.*]] = load [[A]]*, [[A]]** [[THIS]]
Expand Down Expand Up @@ -340,7 +340,7 @@ namespace test8 {
// CHECK-NEXT: [[T4:%.*]] = icmp ne i32 [[T3]], 0
// CHECK-NEXT: br i1 [[T4]]
// -> fallthrough, end
// CHECK: [[INIT:%.*]] = invoke [[TEST8A]]* @_ZN5test81AC1Ev([[TEST8A]]* @_ZZN5test84testEvE1x)
// CHECK: [[INIT:%.*]] = invoke [[TEST8A]]* @_ZN5test81AC1Ev([[TEST8A]]* noalias @_ZZN5test84testEvE1x)

// FIXME: Here we register a global destructor that
// unconditionally calls the destructor. That's what we've always
Expand Down
4 changes: 2 additions & 2 deletions clang/test/CodeGenCXX/arm64-constructor-return.cpp
Expand Up @@ -10,9 +10,9 @@ S::S() {
iField = 1;
};

// CHECK: %struct.S* @_ZN1SC2Ev(%struct.S* returned %this)
// CHECK: %struct.S* @_ZN1SC2Ev(%struct.S* noalias returned %this)

// CHECK: %struct.S* @_ZN1SC1Ev(%struct.S* returned %this)
// CHECK: %struct.S* @_ZN1SC1Ev(%struct.S* noalias returned %this)
// CHECK: [[THISADDR:%[a-zA-Z0-9.]+]] = alloca %struct.S*
// CHECK: store %struct.S* %this, %struct.S** [[THISADDR]]
// CHECK: [[THIS1:%.*]] = load %struct.S*, %struct.S** [[THISADDR]]
Expand Down
6 changes: 3 additions & 3 deletions clang/test/CodeGenCXX/array-default-argument.cpp
Expand Up @@ -17,11 +17,11 @@ void g() {
// CHECK: br label %[[LOOP:.*]]

// [[LOOP]]:
// CHECK: {{call|invoke}} {{.*}} @_ZN1AC1Ev([[TEMPORARY:.*]])
// CHECK: {{call|invoke}} {{.*}} @_ZN1AC1Ev([[SA:.*]]* noalias [[TEMP:.*]])
// CHECK-EH: unwind label %[[PARTIAL_ARRAY_LPAD:.*]]
// CHECK: {{call|invoke}} {{.*}} @_ZN1BC1E1A({{.*}}, [[TEMPORARY]])
// CHECK: {{call|invoke}} {{.*}} @_ZN1BC1E1A([[SB:.*]]* noalias %{{.*}}, [[SA]]* [[TEMP]])
// CHECK-EH: unwind label %[[A_AND_PARTIAL_ARRAY_LPAD:.*]]
// CHECK: {{call|invoke}} {{.*}} @_ZN1AD1Ev([[TEMPORARY]])
// CHECK: {{call|invoke}} {{.*}} @_ZN1AD1Ev([[SA]]* [[TEMP]])
// CHECK-EH: unwind label %[[PARTIAL_ARRAY_LPAD]]
// CHECK: getelementptr {{.*}}, i{{[0-9]*}} 1
// CHECK: icmp eq
Expand Down
8 changes: 4 additions & 4 deletions clang/test/CodeGenCXX/atomicinit.cpp
Expand Up @@ -65,23 +65,23 @@ namespace PR18097 {
};

// CHECK-LABEL: define {{.*}} @__cxx_global_var_init
// CHECK: call void @_ZN7PR180977dynamic1XC1Ei({{.*}}* nonnull @_ZN7PR180977dynamic1aE, i32 1)
// CHECK: call void @_ZN7PR180977dynamic1XC1Ei({{.*}}* noalias nonnull @_ZN7PR180977dynamic1aE, i32 1)
_Atomic(X) a = X(1);

// CHECK-LABEL: define {{.*}} @__cxx_global_var_init
// CHECK: call void @_ZN7PR180977dynamic1XC1Ei({{.*}}* nonnull @_ZN7PR180977dynamic1bE, i32 2)
// CHECK: call void @_ZN7PR180977dynamic1XC1Ei({{.*}}* noalias nonnull @_ZN7PR180977dynamic1bE, i32 2)
_Atomic(X) b(X(2));

// CHECK-LABEL: define {{.*}} @__cxx_global_var_init
// CHECK: call void @_ZN7PR180977dynamic1XC1Ei({{.*}}* nonnull @_ZN7PR180977dynamic1cE, i32 3)
// CHECK: call void @_ZN7PR180977dynamic1XC1Ei({{.*}}* noalias nonnull @_ZN7PR180977dynamic1cE, i32 3)
_Atomic(X) c{X(3)};

struct Y {
_Atomic(X) a;
_Atomic(int) b;
};
// CHECK-LABEL: define {{.*}} @__cxx_global_var_init
// CHECK: call void @_ZN7PR180977dynamic1XC1Ei({{.*}}* getelementptr inbounds ({{.*}}, {{.*}}* @_ZN7PR180977dynamic1yE, i32 0, i32 0), i32 4)
// CHECK: call void @_ZN7PR180977dynamic1XC1Ei({{.*}}* noalias getelementptr inbounds ({{.*}}, {{.*}}* @_ZN7PR180977dynamic1yE, i32 0, i32 0), i32 4)
// CHECK: store i32 5, i32* getelementptr inbounds ({{.*}}, {{.*}}* @_ZN7PR180977dynamic1yE, i32 0, i32 1)
Y y = { X(4), 5 };
}
Expand Down
2 changes: 1 addition & 1 deletion clang/test/CodeGenCXX/blocks-cxx11.cpp
Expand Up @@ -106,7 +106,7 @@ namespace test_block_in_lambda {
// CHECK: [[TO_DESTROY:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
// CHECK: [[T0:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[LAMBDA_T]], [[LAMBDA_T]]* [[THIS]], i32 0, i32 0
// CHECK-NEXT: call void @_ZN20test_block_in_lambda1AC1ERKS0_({{.*}}* [[T0]], {{.*}}* dereferenceable({{[0-9]+}}) [[T1]])
// CHECK-NEXT: call void @_ZN20test_block_in_lambda1AC1ERKS0_({{.*}}* noalias [[T0]], {{.*}}* dereferenceable({{[0-9]+}}) [[T1]])
// CHECK-NEXT: [[T0:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to void ()*
// CHECK-NEXT: call void @_ZN20test_block_in_lambda9takeBlockEU13block_pointerFvvE(void ()* [[T0]])
// CHECK-NEXT: call void @_ZN20test_block_in_lambda1AD1Ev({{.*}}* [[TO_DESTROY]])
Expand Down
8 changes: 4 additions & 4 deletions clang/test/CodeGenCXX/blocks.cpp
Expand Up @@ -127,7 +127,7 @@ namespace test4 {
// CHECK: [[TMP:%.*]] = alloca [[A:%.*]], align 1
// CHECK-NEXT: store i8* [[BLOCKDESC:%.*]], i8** {{.*}}, align 8
// CHECK-NEXT: bitcast i8* [[BLOCKDESC]] to <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]* }>*
// CHECK: call void @_ZN5test41AC1Ev([[A]]* [[TMP]])
// CHECK: call void @_ZN5test41AC1Ev([[A]]* noalias [[TMP]])
// CHECK-NEXT: call void @_ZN5test43fooENS_1AE([[A]]* [[TMP]])
// CHECK-NEXT: call void @_ZN5test41AD1Ev([[A]]* [[TMP]])
// CHECK-NEXT: ret void
Expand Down Expand Up @@ -158,7 +158,7 @@ namespace test5 {
// CHECK-NEXT: [[CLEANUP_ACTIVE:%.*]] = alloca i1
// CHECK-NEXT: [[T0:%.*]] = zext i1
// CHECK-NEXT: store i8 [[T0]], i8* [[COND]], align 1
// CHECK-NEXT: call void @_ZN5test51AC1Ev([[A]]* [[X]])
// CHECK-NEXT: call void @_ZN5test51AC1Ev([[A]]* noalias [[X]])
// CHECK-NEXT: [[CLEANUP_ADDR:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
// CHECK-NEXT: [[T0:%.*]] = load i8, i8* [[COND]], align 1
// CHECK-NEXT: [[T1:%.*]] = trunc i8 [[T0]] to i1
Expand All @@ -167,7 +167,7 @@ namespace test5 {

// CHECK-NOT: br
// CHECK: [[CAPTURE:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
// CHECK-NEXT: call void @_ZN5test51AC1ERKS0_([[A]]* [[CAPTURE]], [[A]]* dereferenceable({{[0-9]+}}) [[X]])
// CHECK-NEXT: call void @_ZN5test51AC1ERKS0_([[A]]* noalias [[CAPTURE]], [[A]]* dereferenceable({{[0-9]+}}) [[X]])
// CHECK-NEXT: store i1 true, i1* [[CLEANUP_ACTIVE]]
// CHECK-NEXT: bitcast [[BLOCK_T]]* [[BLOCK]] to void ()*
// CHECK-NEXT: br label
Expand Down Expand Up @@ -202,7 +202,7 @@ namespace test6 {

// CHECK-LABEL: define void @_ZN5test64testEv()
// CHECK: [[TEMP:%.*]] = alloca [[A:%.*]], align 1
// CHECK-NEXT: call void @_ZN5test61AC1Ev([[A]]* [[TEMP]])
// CHECK-NEXT: call void @_ZN5test61AC1Ev([[A]]* noalias [[TEMP]])
// CHECK-NEXT: call void @_ZN5test63fooERKNS_1AEU13block_pointerFvvE(
// CHECK-NEXT: call void @_ZN5test61AD1Ev([[A]]* [[TEMP]])
// CHECK-NEXT: call void @_ZN5test63barEv()
Expand Down

0 comments on commit cc7e747

Please sign in to comment.