[PATCH] D68340: Add AIX toolchain and basic linker functionality

2019-10-08 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L added inline comments.



Comment at: clang/lib/Driver/ToolChains/AIX.cpp:35
+  // Only support 32 and 64 bit
+  if (!IsArch32Bit && !IsArch64Bit)
+llvm_unreachable("Unsupported bit width value");

Is there any reason to use llvm_unreachable here? I think we should use  
'assertion' instead here:

```
assert((IsArch32Bit || IsArch64Bit) && "...");
```



Comment at: clang/lib/Driver/ToolChains/AIX.cpp:54
+  } else {
+assert(Output.isNothing() && "Invalid output.");
+  }

I am not sure, if we compile with assertion off, does this extra 'else' {} have 
any side effect?



Comment at: clang/lib/Driver/ToolChains/AIX.cpp:70
+
+  if (!Args.hasArg(options::OPT_nostdlib)) {
+const char *crt0 = nullptr;

line 38 and line 70 use the same query, should they be put together? Or is 
there any exact order we should follow to push args into 'CmdArgs'?



Comment at: clang/lib/Driver/ToolChains/AIX.cpp:93
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
+// Support POSIX threads if "-pthreads" or 
+// "-pthread" is present

One line of comment can be <= 80 characters.



Comment at: clang/lib/Driver/ToolChains/AIX.h:33
+const char *LinkingOutput) const override;
+};
+} // end namespace aix

An extra blank line preferred below.



Comment at: clang/lib/Driver/ToolChains/AIX.h:43
+  const llvm::opt::ArgList &Args);
+  ~AIX() override;
+

Since we are not doing anything special in AIX toolchain destructor, seems like 
we don't need to override it?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D68340/new/

https://reviews.llvm.org/D68340



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D68340: Add AIX toolchain and basic linker functionality

2019-10-08 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L added inline comments.



Comment at: clang/lib/Driver/ToolChains/AIX.cpp:38
+
+  if (!Args.hasArg(options::OPT_nostdlib)) {
+CmdArgs.push_back("-e");

Test with Clangtana on terran, when no '-nostdlib' specified, since '-e' & 
'__start' are the default behavior for AIX system linker, so there are no 
explicitly '-e' & '__start' found on linker input commanline, so I am wondering 
do we need to explicitly add them to 'CmdArgs'?



Comment at: clang/lib/Driver/ToolChains/AIX.cpp:47
+  else
+CmdArgs.push_back("-bso");
+

Ditto. Since by default, AIX linker is dynamically linked, '-bso' is implicitly 
set on AIX system linker when testing with Clangtana, so do we need to 
explicitly set '-bso' in LLVM?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D68340/new/

https://reviews.llvm.org/D68340



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D68340: Add AIX toolchain and basic linker functionality

2019-10-22 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L added inline comments.



Comment at: clang/lib/Driver/ToolChains/AIX.cpp:35
+  // Only support 32 and 64 bit
+  if (!IsArch32Bit && !IsArch64Bit)
+llvm_unreachable("Unsupported bit width value");

stevewan wrote:
> jasonliu wrote:
> > Xiangling_L wrote:
> > > Is there any reason to use llvm_unreachable here? I think we should use  
> > > 'assertion' instead here:
> > > 
> > > ```
> > > assert((IsArch32Bit || IsArch64Bit) && "...");
> > > ```
> > IsArch64Bit used only in the assertion could cause warning when the 
> > assertion is turned off. 
> Jason has provided a good point why `llvm_unreachable` was preferred here. 
> Other than that, I believe the two are fairly interchangeable in this 
> particular case. That said, I'm leaning towards keeping `llvm_unreachable`, 
> but definitely add more comment if you have good reasons for using `assert`. 
> Thanks!
Jason is right, I am fine with keeping `llvm_unreachable`.



Comment at: clang/lib/Driver/ToolChains/AIX.cpp:44
+  } else {
+assert(Output.isNothing() && "Invalid output.");
+  }

Glad to know the build without assertion on would not be affected by this. I 
just have slight preference that we don't have this blank block in our product 
code when the assertion is off. Is that better we put this assertion before 
`if` block, and do something like this;

```
assert((Output.isFilename() || Output.isNothing()) && "Invalid output.");

if (Output.isFilename()) {
CmdArgs.push_back("-o");
CmdArgs.push_back(Output.getFilename());
  } 
```


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D68340/new/

https://reviews.llvm.org/D68340



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D74166: [AIX][Frontend] Static init implementation for AIX considering no priority

2020-05-25 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L updated this revision to Diff 266087.
Xiangling_L added a comment.

Adjust  `mangleDynamicDestructor`;
Add assertion and FIXME for getUniqueModuleId


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D74166/new/

https://reviews.llvm.org/D74166

Files:
  clang/include/clang/AST/Mangle.h
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/CodeGen/CGCXXABI.h
  clang/lib/CodeGen/CGDeclCXX.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/CodeGen/CodeGenModule.h
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/CodeGen/aix-constructor-attribute.cpp
  clang/test/CodeGen/aix-destructor-attribute.cpp
  clang/test/CodeGen/aix-init-priority-attribute.cpp
  clang/test/CodeGen/static-init.cpp

Index: clang/test/CodeGen/static-init.cpp
===
--- clang/test/CodeGen/static-init.cpp
+++ clang/test/CodeGen/static-init.cpp
@@ -1,12 +1,55 @@
-// RUN: not %clang_cc1 -triple powerpc-ibm-aix-xcoff -S -emit-llvm -x c++ %s \
-// RUN: -o /dev/null 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -triple powerpc-ibm-aix-xcoff -S -emit-llvm -x c++ < %s \
+// RUN: | FileCheck %s
 
-// RUN: not %clang_cc1 -triple powerpc64-ibm-aix-xcoff -S -emit-llvm -x c++ %s \
-// RUN: -o /dev/null 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -triple powerpc64-ibm-aix-xcoff -S -emit-llvm -x c++ < %s \
+// RUN: | FileCheck %s
 
 struct test {
   test();
   ~test();
 } t;
 
-// CHECK: error in backend: Static initialization has not been implemented on XL ABI yet.
+// CHECK: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @__sinit8000_clang_6a64b8be19fb12e74feab8a7a858f83b, i8* null }]
+// CHECK: @llvm.global_dtors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @__sterm8000_clang_6a64b8be19fb12e74feab8a7a858f83b, i8* null }]
+// CHECK: define internal void @__cxx_global_var_init() #0 {
+// CHECK: entry:
+// CHECK:   call void @_ZN4testC1Ev(%struct.test* @t)
+// CHECK:   %0 = call i32 @atexit(void ()* @__dtor_t)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__dtor_t() #0 {
+// CHECK: entry:
+// CHECK:   call void @_ZN4testD1Ev(%struct.test* @t)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: declare i32 @atexit(void ()*)
+
+// CHECK: define internal void @__cxx_global_var_destruct_t() #0 {
+// CHECK: entry:
+// CHECK:   %0 = call i32 @unatexit(void ()* @__dtor_t)
+// CHECK:   %guard.hasSrterm = icmp eq i32 %0, 0
+// CHECK:   br i1 %guard.hasSrterm, label %destruct.check, label %destruct.end
+
+// CHECK: destruct.check:
+// CHECK:   call void @__dtor_t()
+// CHECK:   br label %destruct.end
+
+// CHECK: destruct.end:
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: declare i32 @unatexit(void ()*)
+
+// CHECK: define dso_local void @__sinit8000_clang_6a64b8be19fb12e74feab8a7a858f83b() #0 {
+// CHECK: entry:
+// CHECK:   call void @__cxx_global_var_init()
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define dso_local void @__sterm8000_clang_6a64b8be19fb12e74feab8a7a858f83b() #0 {
+// CHECK: entry:
+// CHECK:   call void @__cxx_global_var_destruct_t()
+// CHECK:   ret void
+// CHECK: }
Index: clang/test/CodeGen/aix-init-priority-attribute.cpp
===
--- /dev/null
+++ clang/test/CodeGen/aix-init-priority-attribute.cpp
@@ -0,0 +1,17 @@
+// RUN: not %clang_cc1 -triple powerpc-ibm-aix-xcoff -x c++ -emit-llvm < %s \
+// RUN: 2>&1 | FileCheck %s
+// RUN: not %clang_cc1 -triple powerpc64-ibm-aix-xcoff -x c++ -emit-llvm < %s \
+// RUN: 2>&1 | FileCheck %s
+
+class test {
+  int a;
+
+public:
+  test(int c) { a = c; }
+  ~test() { a = 0; }
+};
+
+__attribute__((init_priority(2000)))
+test t(1);
+
+// CHECK: fatal error: error in backend: 'init_priority' attribute unsupported on AIX yet
Index: clang/test/CodeGen/aix-destructor-attribute.cpp
===
--- /dev/null
+++ clang/test/CodeGen/aix-destructor-attribute.cpp
@@ -0,0 +1,18 @@
+// RUN: not %clang_cc1 -triple powerpc-ibm-aix-xcoff -x c++ -emit-llvm < %s \
+// RUN: 2>&1 | FileCheck %s
+// RUN: not %clang_cc1 -triple powerpc64-ibm-aix-xcoff -x c++ -emit-llvm < %s \
+// RUN: 2>&1 | FileCheck %s
+
+int bar() __attribute__((destructor(180)));
+
+class test {
+  int a;
+
+public:
+  test(int c) { a = c; }
+  ~test() { a = 0; }
+};
+
+test t(1);
+
+// CHECK: fatal error: error in backend: 'destructor' attribute unsupported on AIX yet
Index: clang/test/CodeGen/aix-constructor-attribute.cpp
===
--- /dev/null
+++ clang/test/CodeGen/aix-constructor-attribute.cpp
@@ -0,0 +1,18 @@
+// RUN: not %clang_cc1 -triple powerpc-ibm-aix-xcoff -x c++ -emit-llvm < %s \
+// RUN: 2>&1 | FileCheck %s
+// RUN: not %clang_cc1 -triple powerpc64-ibm-aix-xcoff -x c++ -emit-llvm < %

[PATCH] D83702: [AIX]Generate debug info for static init related functions

2020-07-16 Thread Xiangling Liao via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG69f3378ad65b: [AIX]Generate debug info for static init 
related functions (authored by Xiangling_L).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D83702/new/

https://reviews.llvm.org/D83702

Files:
  clang/lib/CodeGen/CGDeclCXX.cpp
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/test/CodeGenCXX/aix-static-init-debug-info.cpp


Index: clang/test/CodeGenCXX/aix-static-init-debug-info.cpp
===
--- /dev/null
+++ clang/test/CodeGenCXX/aix-static-init-debug-info.cpp
@@ -0,0 +1,64 @@
+// RUN: %clang_cc1 -triple powerpc-ibm-aix-xcoff -emit-llvm -x c++ \
+// RUN: -debug-info-kind=limited < %s | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK64 %s
+
+// RUN: %clang_cc1 -triple powerpc64-ibm-aix-xcoff -emit-llvm -x c++ \
+// RUN: -debug-info-kind=limited  < %s | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK64 %s
+
+struct X {
+  X();
+  ~X();
+};
+
+X v;
+
+// CHECK: define internal void @__cxx_global_var_init() [[ATTR:#[0-9]+]] !dbg 
![[DBGVAR16:[0-9]+]] {
+// CHECK: entry:
+// CHECK:   call void @_ZN1XC1Ev(%struct.X* @v), !dbg ![[DBGVAR19:[0-9]+]]
+// CHECK:   %0 = call i32 @atexit(void ()* @__dtor_v) [[ATTR:#[0-9]+]], !dbg 
![[DBGVAR19]]
+// CHECK:   ret void, !dbg ![[DBGVAR19]]
+// CHECK: }
+
+// CHECK: define internal void @__dtor_v() [[ATTR:#[0-9]+]] !dbg 
![[DBGVAR20:[0-9]+]] {
+// CHECK: entry:
+// CHECK:   call void @_ZN1XD1Ev(%struct.X* @v), !dbg ![[DBGVAR21:[0-9]+]]
+// CHECK:   ret void, !dbg ![[DBGVAR21]]
+// CHECK: }
+
+// CHECK: define internal void @__finalize_v() [[ATTR:#[0-9]+]] !dbg 
![[DBGVAR22:[0-9]+]] {
+// CHECK: entry:
+// CHECK:   %0 = call i32 @unatexit(void ()* @__dtor_v) [[ATTR:#[0-9]+]], !dbg 
![[DBGVAR24:[0-9]+]]
+// CHECK:   %needs_destruct = icmp eq i32 %0, 0, !dbg ![[DBGVAR24]]
+// CHECK:   br i1 %needs_destruct, label %destruct.call, label %destruct.end, 
!dbg ![[DBGVAR24]]
+
+// CHECK: destruct.call:
+// CHECK:   call void @__dtor_v(), !dbg ![[DBGVAR24]]
+// CHECK:   br label %destruct.end, !dbg ![[DBGVAR24]]
+
+// CHECK: destruct.end:
+// CHECK:   ret void, !dbg ![[DBGVAR24]]
+// CHECK: }
+
+// CHECK: define void 
@__sinit8000_clang_c3236cbaa79f2bae3a15e6379a05f625() [[ATTR:#[0-9]+]] !dbg 
![[DBGVAR25:[0-9]+]] {
+// CHECK: entry:
+// CHECK:   call void @__cxx_global_var_init(), !dbg ![[DBGVAR26:[0-9]+]]
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define void 
@__sterm8000_clang_c3236cbaa79f2bae3a15e6379a05f625() [[ATTR:#[0-9]+]] !dbg 
![[DBGVAR27:[0-9]+]] {
+// CHECK: entry:
+// CHECK:   call void @__finalize_v(), !dbg ![[DBGVAR28:[0-9]+]]
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: ![[DBGVAR16]] = distinct !DISubprogram(name: 
"__cxx_global_var_init", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: 14, type: 
!{{[0-9]+}}, scopeLine: 14, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, 
unit: !{{[0-9]+}}, retainedNodes: !{{[0-9]+}})
+// CHECK: ![[DBGVAR19]] = !DILocation(line: 14, column: 3, scope: 
![[DBGVAR16]])
+// CHECK: ![[DBGVAR20]] = distinct !DISubprogram(name: "__dtor_v", scope: 
!{{[0-9]+}}, file: !{{[0-9]+}}, line: 14, type: !{{[0-9]+}}, scopeLine: 14, 
spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !{{[0-9]+}}, 
retainedNodes: !{{[0-9]+}})
+// CHECK: ![[DBGVAR21]] = !DILocation(line: 14, column: 3, scope: 
![[DBGVAR20]])
+// CHECK: ![[DBGVAR22]] = distinct !DISubprogram(linkageName: "__finalize_v", 
scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: 14, type: !{{[0-9]+}}, scopeLine: 
14, flags: DIFlagArtificial, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, 
unit: !{{[0-9]+}}, retainedNodes: !{{[0-9]+}})
+// CHECK: ![[DBGVAR24]] = !DILocation(line: 14, column: 3, scope: 
![[DBGVAR22]])
+// CHECK: ![[DBGVAR25]] = distinct !DISubprogram(linkageName: 
"__sinit8000_clang_c3236cbaa79f2bae3a15e6379a05f625", scope: !{{[0-9]+}}, 
file: !{{[0-9]+}}, type: !{{[0-9]+}}, flags: DIFlagArtificial, spFlags: 
DISPFlagDefinition, unit: !{{[0-9]+}}, retainedNodes: !{{[0-9]+}})
+// CHECK: ![[DBGVAR26]] = !DILocation(line: 0, scope: ![[DBGVAR25]])
+// CHECK: ![[DBGVAR27]] = distinct !DISubprogram(linkageName: 
"__sterm8000_clang_c3236cbaa79f2bae3a15e6379a05f625", scope: !{{[0-9]+}}, 
file: !{{[0-9]+}}, type: !{{[0-9]+}}, flags: DIFlagArtificial, spFlags: 
DISPFlagDefinition, unit: !{{[0-9]+}}, retainedNodes: !{{[0-9]+}})
+// CHECK: ![[DBGVAR28]] = !DILocation(line: 0, scope: ![[DBGVAR27]])
Index: clang/lib/CodeGen/ItaniumCXXABI.cpp
===
--- clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -4567,7 +4567,8 @@
   CodeGenFunction CGF(CGM);
 
   CGF.StartFunction(GlobalDecl(), CGM.getContext().VoidTy, StermFinalizer, FI,
-FunctionArgList());
+FunctionArgList(), D.getLocation(),
+D.getInit()->getE

[PATCH] D83974: [AIX] report_fatal_error on `-fregister_global_dtors_with_atexit` for static init

2020-07-16 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L created this revision.
Xiangling_L added reviewers: jasonliu, hubert.reinterpretcast, yusra.syeda.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

On AIX, the semantic of global_dtors contains `__sterm` functions associated 
with C++ cleanup actions and user-declared `__attribute__((__destructor__))` 
functions. We will never register `__sterm` with `atexit()`, so currently 
`-fregister_global_dtors_with_atexit` does not work well on AIX. We need to 
figure out a way to handle that when we start supporting user-declared 
__attribute__((__destructor__)) functions.

Currently we `report_fatal_error` on this option temporarily.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D83974

Files:
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/test/CodeGenCXX/aix-sinit-register-global-dtors-with-atexit.cpp
  clang/test/Driver/cxa-atexit.cpp


Index: clang/test/Driver/cxa-atexit.cpp
===
--- clang/test/Driver/cxa-atexit.cpp
+++ clang/test/Driver/cxa-atexit.cpp
@@ -36,6 +36,7 @@
 // RUN: FileCheck --check-prefix=WITHATEXIT %s
 // RUN: %clang -target x86_64-apple-darwin -c -mkernel -### %s 2>&1 | \
 // RUN: FileCheck --check-prefix=WITHOUTATEXIT %s
+
 // RUN: %clang -target x86_64-pc-linux-gnu -fregister-global-dtors-with-atexit 
-fno-register-global-dtors-with-atexit -c -### %s 2>&1 | \
 // RUN: FileCheck --check-prefix=WITHOUTATEXIT %s
 // RUN: %clang -target x86_64-pc-linux-gnu 
-fno-register-global-dtors-with-atexit -fregister-global-dtors-with-atexit -c 
-### %s 2>&1 | \
@@ -43,5 +44,18 @@
 // RUN: %clang -target x86_64-pc-linux-gnu -c -### %s 2>&1 | \
 // RUN: FileCheck --check-prefix=WITHOUTATEXIT %s
 
+// RUN: %clang -target powerpc-ibm-aix-xcoff 
-fregister-global-dtors-with-atexit -fno-register-global-dtors-with-atexit -c 
-### %s 2>&1 | \
+// RUN: FileCheck --check-prefix=WITHOUTATEXIT %s
+// RUN: %clang -target powerpc-ibm-aix-xcoff 
-fno-register-global-dtors-with-atexit -fregister-global-dtors-with-atexit -c 
-### %s 2>&1 | \
+// RUN: FileCheck --check-prefix=WITHATEXIT %s
+// RUN: %clang -target powerpc-ibm-aix-xcoff -c -### %s 2>&1 | \
+// RUN: FileCheck --check-prefix=WITHOUTATEXIT %s
+// RUN: %clang -target powerpc64-ibm-aix-xcoff 
-fregister-global-dtors-with-atexit -fno-register-global-dtors-with-atexit -c 
-### %s 2>&1 | \
+// RUN: FileCheck --check-prefix=WITHOUTATEXIT %s
+// RUN: %clang -target powerpc64-ibm-aix-xcoff 
-fno-register-global-dtors-with-atexit -fregister-global-dtors-with-atexit -c 
-### %s 2>&1 | \
+// RUN: FileCheck --check-prefix=WITHATEXIT %s
+// RUN: %clang -target powerpc64-ibm-aix-xcoff -c -### %s 2>&1 | \
+// RUN: FileCheck --check-prefix=WITHOUTATEXIT %s
+
 // WITHATEXIT: -fregister-global-dtors-with-atexit
 // WITHOUTATEXIT-NOT: -fregister-global-dtors-with-atexit
Index: clang/test/CodeGenCXX/aix-sinit-register-global-dtors-with-atexit.cpp
===
--- /dev/null
+++ clang/test/CodeGenCXX/aix-sinit-register-global-dtors-with-atexit.cpp
@@ -0,0 +1,14 @@
+// RUN: not %clang_cc1 -triple powerpc-ibm-aix-xcoff -S -emit-llvm -x c++ \
+// RUN: -fregister-global-dtors-with-atexit < %s 2>&1 | \
+// RUN:   FileCheck %s
+
+// RUN: not %clang_cc1 -triple powerpc64-ibm-aix-xcoff -S -emit-llvm -x c++ \
+// RUN: -fregister-global-dtors-with-atexit < %s 2>&1 | \
+// RUN:   FileCheck %s
+
+struct T{
+T();
+~T();
+} t;
+
+// CHECK: error in backend: register global dtors with atexit() is not 
supported on AIX yet
Index: clang/lib/CodeGen/CodeGenModule.cpp
===
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -1209,6 +1209,9 @@
 /// when the module is unloaded.
 void CodeGenModule::AddGlobalDtor(llvm::Function *Dtor, int Priority) {
   if (CodeGenOpts.RegisterGlobalDtorsWithAtExit) {
+if (getContext().getTargetInfo().getTriple().isOSAIX())
+  llvm::report_fatal_error(
+  "register global dtors with atexit() is not supported on AIX yet");
 DtorsUsingAtExit[Priority].push_back(Dtor);
 return;
   }


Index: clang/test/Driver/cxa-atexit.cpp
===
--- clang/test/Driver/cxa-atexit.cpp
+++ clang/test/Driver/cxa-atexit.cpp
@@ -36,6 +36,7 @@
 // RUN: FileCheck --check-prefix=WITHATEXIT %s
 // RUN: %clang -target x86_64-apple-darwin -c -mkernel -### %s 2>&1 | \
 // RUN: FileCheck --check-prefix=WITHOUTATEXIT %s
+
 // RUN: %clang -target x86_64-pc-linux-gnu -fregister-global-dtors-with-atexit -fno-register-global-dtors-with-atexit -c -### %s 2>&1 | \
 // RUN: FileCheck --check-prefix=WITHOUTATEXIT %s
 // RUN: %clang -target x86_64-pc-linux-gnu -fno-register-global-dtors-with-atexit -fregister-global-dtors-with-atexit -c -### %s 2>&1 | \
@@ -43,5 +44,18 @@
 // RUN: %clang -target x86_64-pc-linux-gnu -c -### %s 2>&1 | \
 // RUN: FileCheck 

[PATCH] D83974: [AIX] report_fatal_error on `-fregister_global_dtors_with_atexit` for static init

2020-07-17 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L updated this revision to Diff 278777.
Xiangling_L marked 2 inline comments as done.
Xiangling_L added a comment.

Adjust the quesry;


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D83974/new/

https://reviews.llvm.org/D83974

Files:
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/test/CodeGenCXX/aix-sinit-register-global-dtors-with-atexit.cpp
  clang/test/Driver/cxa-atexit.cpp


Index: clang/test/Driver/cxa-atexit.cpp
===
--- clang/test/Driver/cxa-atexit.cpp
+++ clang/test/Driver/cxa-atexit.cpp
@@ -36,6 +36,7 @@
 // RUN: FileCheck --check-prefix=WITHATEXIT %s
 // RUN: %clang -target x86_64-apple-darwin -c -mkernel -### %s 2>&1 | \
 // RUN: FileCheck --check-prefix=WITHOUTATEXIT %s
+
 // RUN: %clang -target x86_64-pc-linux-gnu -fregister-global-dtors-with-atexit 
-fno-register-global-dtors-with-atexit -c -### %s 2>&1 | \
 // RUN: FileCheck --check-prefix=WITHOUTATEXIT %s
 // RUN: %clang -target x86_64-pc-linux-gnu 
-fno-register-global-dtors-with-atexit -fregister-global-dtors-with-atexit -c 
-### %s 2>&1 | \
@@ -43,5 +44,18 @@
 // RUN: %clang -target x86_64-pc-linux-gnu -c -### %s 2>&1 | \
 // RUN: FileCheck --check-prefix=WITHOUTATEXIT %s
 
+// RUN: %clang -target powerpc-ibm-aix-xcoff 
-fregister-global-dtors-with-atexit -fno-register-global-dtors-with-atexit -c 
-### %s 2>&1 | \
+// RUN: FileCheck --check-prefix=WITHOUTATEXIT %s
+// RUN: %clang -target powerpc-ibm-aix-xcoff 
-fno-register-global-dtors-with-atexit -fregister-global-dtors-with-atexit -c 
-### %s 2>&1 | \
+// RUN: FileCheck --check-prefix=WITHATEXIT %s
+// RUN: %clang -target powerpc-ibm-aix-xcoff -c -### %s 2>&1 | \
+// RUN: FileCheck --check-prefix=WITHOUTATEXIT %s
+// RUN: %clang -target powerpc64-ibm-aix-xcoff 
-fregister-global-dtors-with-atexit -fno-register-global-dtors-with-atexit -c 
-### %s 2>&1 | \
+// RUN: FileCheck --check-prefix=WITHOUTATEXIT %s
+// RUN: %clang -target powerpc64-ibm-aix-xcoff 
-fno-register-global-dtors-with-atexit -fregister-global-dtors-with-atexit -c 
-### %s 2>&1 | \
+// RUN: FileCheck --check-prefix=WITHATEXIT %s
+// RUN: %clang -target powerpc64-ibm-aix-xcoff -c -### %s 2>&1 | \
+// RUN: FileCheck --check-prefix=WITHOUTATEXIT %s
+
 // WITHATEXIT: -fregister-global-dtors-with-atexit
 // WITHOUTATEXIT-NOT: -fregister-global-dtors-with-atexit
Index: clang/test/CodeGenCXX/aix-sinit-register-global-dtors-with-atexit.cpp
===
--- /dev/null
+++ clang/test/CodeGenCXX/aix-sinit-register-global-dtors-with-atexit.cpp
@@ -0,0 +1,14 @@
+// RUN: not %clang_cc1 -triple powerpc-ibm-aix-xcoff -S -emit-llvm -x c++ \
+// RUN: -fregister-global-dtors-with-atexit < %s 2>&1 | \
+// RUN:   FileCheck %s
+
+// RUN: not %clang_cc1 -triple powerpc64-ibm-aix-xcoff -S -emit-llvm -x c++ \
+// RUN: -fregister-global-dtors-with-atexit < %s 2>&1 | \
+// RUN:   FileCheck %s
+
+struct T {
+  T();
+  ~T();
+} t;
+
+// CHECK: error in backend: register global dtors with atexit() is not 
supported yet
Index: clang/lib/CodeGen/CodeGenModule.cpp
===
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -1209,6 +1209,9 @@
 /// when the module is unloaded.
 void CodeGenModule::AddGlobalDtor(llvm::Function *Dtor, int Priority) {
   if (CodeGenOpts.RegisterGlobalDtorsWithAtExit) {
+if (getCXXABI().useSinitAndSterm())
+  llvm::report_fatal_error(
+  "register global dtors with atexit() is not supported yet");
 DtorsUsingAtExit[Priority].push_back(Dtor);
 return;
   }


Index: clang/test/Driver/cxa-atexit.cpp
===
--- clang/test/Driver/cxa-atexit.cpp
+++ clang/test/Driver/cxa-atexit.cpp
@@ -36,6 +36,7 @@
 // RUN: FileCheck --check-prefix=WITHATEXIT %s
 // RUN: %clang -target x86_64-apple-darwin -c -mkernel -### %s 2>&1 | \
 // RUN: FileCheck --check-prefix=WITHOUTATEXIT %s
+
 // RUN: %clang -target x86_64-pc-linux-gnu -fregister-global-dtors-with-atexit -fno-register-global-dtors-with-atexit -c -### %s 2>&1 | \
 // RUN: FileCheck --check-prefix=WITHOUTATEXIT %s
 // RUN: %clang -target x86_64-pc-linux-gnu -fno-register-global-dtors-with-atexit -fregister-global-dtors-with-atexit -c -### %s 2>&1 | \
@@ -43,5 +44,18 @@
 // RUN: %clang -target x86_64-pc-linux-gnu -c -### %s 2>&1 | \
 // RUN: FileCheck --check-prefix=WITHOUTATEXIT %s
 
+// RUN: %clang -target powerpc-ibm-aix-xcoff -fregister-global-dtors-with-atexit -fno-register-global-dtors-with-atexit -c -### %s 2>&1 | \
+// RUN: FileCheck --check-prefix=WITHOUTATEXIT %s
+// RUN: %clang -target powerpc-ibm-aix-xcoff -fno-register-global-dtors-with-atexit -fregister-global-dtors-with-atexit -c -### %s 2>&1 | \
+// RUN: FileCheck --check-prefix=WITHATEXIT %s
+// RUN: %clang -target powerpc-ibm-aix-xcoff -c -### %s 2>&1 | \
+// RUN: FileCheck --check-prefix=WITHOUTATEXIT %s
+/

[PATCH] D83974: [AIX] report_fatal_error on `-fregister_global_dtors_with_atexit` for static init

2020-07-17 Thread Xiangling Liao via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGec6ada62643c: [AIX] report_fatal_error on 
`-fregister_global_dtors_with_atexit` for static… (authored by Xiangling_L).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D83974/new/

https://reviews.llvm.org/D83974

Files:
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/test/CodeGenCXX/aix-sinit-register-global-dtors-with-atexit.cpp
  clang/test/Driver/cxa-atexit.cpp


Index: clang/test/Driver/cxa-atexit.cpp
===
--- clang/test/Driver/cxa-atexit.cpp
+++ clang/test/Driver/cxa-atexit.cpp
@@ -36,6 +36,7 @@
 // RUN: FileCheck --check-prefix=WITHATEXIT %s
 // RUN: %clang -target x86_64-apple-darwin -c -mkernel -### %s 2>&1 | \
 // RUN: FileCheck --check-prefix=WITHOUTATEXIT %s
+
 // RUN: %clang -target x86_64-pc-linux-gnu -fregister-global-dtors-with-atexit 
-fno-register-global-dtors-with-atexit -c -### %s 2>&1 | \
 // RUN: FileCheck --check-prefix=WITHOUTATEXIT %s
 // RUN: %clang -target x86_64-pc-linux-gnu 
-fno-register-global-dtors-with-atexit -fregister-global-dtors-with-atexit -c 
-### %s 2>&1 | \
@@ -43,5 +44,18 @@
 // RUN: %clang -target x86_64-pc-linux-gnu -c -### %s 2>&1 | \
 // RUN: FileCheck --check-prefix=WITHOUTATEXIT %s
 
+// RUN: %clang -target powerpc-ibm-aix-xcoff 
-fregister-global-dtors-with-atexit -fno-register-global-dtors-with-atexit -c 
-### %s 2>&1 | \
+// RUN: FileCheck --check-prefix=WITHOUTATEXIT %s
+// RUN: %clang -target powerpc-ibm-aix-xcoff 
-fno-register-global-dtors-with-atexit -fregister-global-dtors-with-atexit -c 
-### %s 2>&1 | \
+// RUN: FileCheck --check-prefix=WITHATEXIT %s
+// RUN: %clang -target powerpc-ibm-aix-xcoff -c -### %s 2>&1 | \
+// RUN: FileCheck --check-prefix=WITHOUTATEXIT %s
+// RUN: %clang -target powerpc64-ibm-aix-xcoff 
-fregister-global-dtors-with-atexit -fno-register-global-dtors-with-atexit -c 
-### %s 2>&1 | \
+// RUN: FileCheck --check-prefix=WITHOUTATEXIT %s
+// RUN: %clang -target powerpc64-ibm-aix-xcoff 
-fno-register-global-dtors-with-atexit -fregister-global-dtors-with-atexit -c 
-### %s 2>&1 | \
+// RUN: FileCheck --check-prefix=WITHATEXIT %s
+// RUN: %clang -target powerpc64-ibm-aix-xcoff -c -### %s 2>&1 | \
+// RUN: FileCheck --check-prefix=WITHOUTATEXIT %s
+
 // WITHATEXIT: -fregister-global-dtors-with-atexit
 // WITHOUTATEXIT-NOT: -fregister-global-dtors-with-atexit
Index: clang/test/CodeGenCXX/aix-sinit-register-global-dtors-with-atexit.cpp
===
--- /dev/null
+++ clang/test/CodeGenCXX/aix-sinit-register-global-dtors-with-atexit.cpp
@@ -0,0 +1,14 @@
+// RUN: not %clang_cc1 -triple powerpc-ibm-aix-xcoff -S -emit-llvm -x c++ \
+// RUN: -fregister-global-dtors-with-atexit < %s 2>&1 | \
+// RUN:   FileCheck %s
+
+// RUN: not %clang_cc1 -triple powerpc64-ibm-aix-xcoff -S -emit-llvm -x c++ \
+// RUN: -fregister-global-dtors-with-atexit < %s 2>&1 | \
+// RUN:   FileCheck %s
+
+struct T {
+  T();
+  ~T();
+} t;
+
+// CHECK: error in backend: register global dtors with atexit() is not 
supported yet
Index: clang/lib/CodeGen/CodeGenModule.cpp
===
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -1209,6 +1209,9 @@
 /// when the module is unloaded.
 void CodeGenModule::AddGlobalDtor(llvm::Function *Dtor, int Priority) {
   if (CodeGenOpts.RegisterGlobalDtorsWithAtExit) {
+if (getCXXABI().useSinitAndSterm())
+  llvm::report_fatal_error(
+  "register global dtors with atexit() is not supported yet");
 DtorsUsingAtExit[Priority].push_back(Dtor);
 return;
   }


Index: clang/test/Driver/cxa-atexit.cpp
===
--- clang/test/Driver/cxa-atexit.cpp
+++ clang/test/Driver/cxa-atexit.cpp
@@ -36,6 +36,7 @@
 // RUN: FileCheck --check-prefix=WITHATEXIT %s
 // RUN: %clang -target x86_64-apple-darwin -c -mkernel -### %s 2>&1 | \
 // RUN: FileCheck --check-prefix=WITHOUTATEXIT %s
+
 // RUN: %clang -target x86_64-pc-linux-gnu -fregister-global-dtors-with-atexit -fno-register-global-dtors-with-atexit -c -### %s 2>&1 | \
 // RUN: FileCheck --check-prefix=WITHOUTATEXIT %s
 // RUN: %clang -target x86_64-pc-linux-gnu -fno-register-global-dtors-with-atexit -fregister-global-dtors-with-atexit -c -### %s 2>&1 | \
@@ -43,5 +44,18 @@
 // RUN: %clang -target x86_64-pc-linux-gnu -c -### %s 2>&1 | \
 // RUN: FileCheck --check-prefix=WITHOUTATEXIT %s
 
+// RUN: %clang -target powerpc-ibm-aix-xcoff -fregister-global-dtors-with-atexit -fno-register-global-dtors-with-atexit -c -### %s 2>&1 | \
+// RUN: FileCheck --check-prefix=WITHOUTATEXIT %s
+// RUN: %clang -target powerpc-ibm-aix-xcoff -fno-register-global-dtors-with-atexit -fregister-global-dtors-with-atexit -c -### %s 2>&1 | \
+// RUN: FileCheck --check-prefix=WITHATEXIT %s
+// RUN: %cla

[PATCH] D79719: [AIX] Implement AIX special alignment rule about double/long double

2020-07-22 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L marked 13 inline comments as done.
Xiangling_L added inline comments.



Comment at: clang/lib/AST/ASTContext.cpp:2418
+
   if (!Target->allowsLargerPreferedTypeAlignment())
 return ABIAlign;

jasonliu wrote:
> Should this if statement go above the `if (const auto *RT = 
> T->getAs()) ` ?
> When Target does not allow larger prefered type alignment, then we should 
> return ABIAlign immediately without going through the RecordType query?
Agree. I will update this.



Comment at: clang/test/Layout/aix-double-struct-member.cpp:2
+// RUN: %clang_cc1 -emit-llvm-only -triple powerpc-ibm-aix-xcoff \
+// RUN: -fdump-record-layouts -fsyntax-only -x c++ %s | \
+// RUN:   FileCheck %s

jasonliu wrote:
> You are not using ` < %s` here. So `-x c++` is redundant?
Yeah, thanks, I will remove it.



Comment at: clang/test/Layout/aix-no-unique-address-with-double.cpp:138
+// CHECK-NEXT:|  nvsize=8, nvalign=4, preferrednvalign=4]
+
+int a = sizeof(Empty);

jasonliu wrote:
> I think this case is interesting and may worth adding too:
> ```
> struct F {
>   [[no_unique_address]] Empty emp, emp2;
>   double d;
> };
> ```
Sure.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79719/new/

https://reviews.llvm.org/D79719



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D79719: [AIX] Implement AIX special alignment rule about double/long double

2020-07-22 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L updated this revision to Diff 279930.
Xiangling_L marked 3 inline comments as done.
Xiangling_L added a comment.

Add one more testcase;
Addressed other comments;


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79719/new/

https://reviews.llvm.org/D79719

Files:
  clang/include/clang/AST/RecordLayout.h
  clang/include/clang/Basic/TargetInfo.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/RecordLayout.cpp
  clang/lib/AST/RecordLayoutBuilder.cpp
  clang/lib/Basic/Targets/OSTargets.h
  clang/lib/Basic/Targets/PPC.h
  clang/test/Layout/aix-Wpacked-expecting-diagnostics.cpp
  clang/test/Layout/aix-Wpacked-no-diagnostics.cpp
  clang/test/Layout/aix-double-struct-member.cpp
  clang/test/Layout/aix-no-unique-address-with-double.cpp
  clang/test/Layout/aix-pack-attr-on-base.cpp
  clang/test/Layout/aix-power-alignment-typedef.cpp
  clang/test/Layout/aix-virtual-function-and-base-with-double.cpp

Index: clang/test/Layout/aix-virtual-function-and-base-with-double.cpp
===
--- /dev/null
+++ clang/test/Layout/aix-virtual-function-and-base-with-double.cpp
@@ -0,0 +1,112 @@
+// RUN: %clang_cc1 -emit-llvm-only -triple powerpc-ibm-aix-xcoff \
+// RUN: -fdump-record-layouts -fsyntax-only %s | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK32 %s
+
+// RUN: %clang_cc1 -emit-llvm-only -triple powerpc64-ibm-aix-xcoff \
+// RUN: -fdump-record-layouts -fsyntax-only %s | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK64 %s
+
+namespace test1 {
+struct A {
+  double d1;
+  virtual void boo() {}
+};
+
+struct B {
+  double d2;
+  A a;
+};
+
+struct C : public A {
+  double d3;
+};
+
+int i = sizeof(B);
+int j = sizeof(C);
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::A
+// CHECK-NEXT:0 |   (A vtable pointer)
+// CHECK32-NEXT:  4 |   double d1
+// CHECK32-NEXT:| [sizeof=12, dsize=12, align=4, preferredalign=4,
+// CHECK32-NEXT:|  nvsize=12, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:  8 |   double d1
+// CHECK64-NEXT:| [sizeof=16, dsize=16, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=16, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::B
+// CHECK-NEXT:0 |   double d2
+// CHECK-NEXT:8 |   struct test1::A a
+// CHECK-NEXT:8 | (A vtable pointer)
+// CHECK32-NEXT: 12 | double d1
+// CHECK32-NEXT:| [sizeof=24, dsize=20, align=4, preferredalign=8,
+// CHECK32-NEXT:|  nvsize=20, nvalign=4, preferrednvalign=8]
+// CHECK64-NEXT: 16 | double d1
+// CHECK64-NEXT:| [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=24, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::C
+// CHECK-NEXT:0 |   struct test1::A (primary base)
+// CHECK-NEXT:0 | (A vtable pointer)
+// CHECK32-NEXT:  4 | double d1
+// CHECK32-NEXT: 12 |   double d3
+// CHECK32-NEXT:| [sizeof=20, dsize=20, align=4, preferredalign=4,
+// CHECK32-NEXT:|  nvsize=20, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:  8 | double d1
+// CHECK64-NEXT: 16 |   double d3
+// CHECK64-NEXT:| [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=24, nvalign=8, preferrednvalign=8]
+
+} // namespace test1
+
+namespace test2 {
+struct A {
+  long long l1;
+};
+
+struct B : public virtual A {
+  double d2;
+};
+
+#pragma pack(2)
+struct C : public virtual A {
+  double __attribute__((aligned(4))) d3;
+};
+
+int i = sizeof(B);
+int j = sizeof(C);
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::A
+// CHECK-NEXT:0 |   long long l1
+// CHECK-NEXT:  | [sizeof=8, dsize=8, align=8, preferredalign=8,
+// CHECK-NEXT:  |  nvsize=8, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::B
+// CHECK-NEXT:0 |   (B vtable pointer)
+// CHECK32-NEXT:  4 |   double d2
+// CHECK64-NEXT:  8 |   double d2
+// CHECK-NEXT:   16 |   struct test2::A (virtual base)
+// CHECK-NEXT:   16 | long long l1
+// CHECK-NEXT:  | [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK32-NEXT:|  nvsize=12, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:|  nvsize=16, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::C
+// CHECK-NEXT:0 |   (C vtable pointer)
+// CHECK32-NEXT:  4 |   double d3
+// CHECK32-NEXT: 12 |   stru

[PATCH] D79719: [AIX] Implement AIX special alignment rule about double/long double

2020-07-22 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L updated this revision to Diff 279991.
Xiangling_L added a comment.

- Simplified the test command line;
- Split the `typedef` related tests into two to address the LIT testcase 
failure on windows platform;


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79719/new/

https://reviews.llvm.org/D79719

Files:
  clang/include/clang/AST/RecordLayout.h
  clang/include/clang/Basic/TargetInfo.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/RecordLayout.cpp
  clang/lib/AST/RecordLayoutBuilder.cpp
  clang/lib/Basic/Targets/OSTargets.h
  clang/lib/Basic/Targets/PPC.h
  clang/test/Layout/aix-Wpacked-expecting-diagnostics.cpp
  clang/test/Layout/aix-Wpacked-no-diagnostics.cpp
  clang/test/Layout/aix-double-struct-member.cpp
  clang/test/Layout/aix-no-unique-address-with-double.cpp
  clang/test/Layout/aix-pack-attr-on-base.cpp
  clang/test/Layout/aix-power-alignment-typedef-2.cpp
  clang/test/Layout/aix-power-alignment-typedef.cpp
  clang/test/Layout/aix-virtual-function-and-base-with-double.cpp

Index: clang/test/Layout/aix-virtual-function-and-base-with-double.cpp
===
--- /dev/null
+++ clang/test/Layout/aix-virtual-function-and-base-with-double.cpp
@@ -0,0 +1,112 @@
+// RUN: %clang_cc1 -triple powerpc-ibm-aix-xcoff -fdump-record-layouts \
+// RUN: -fsyntax-only %s | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK32 %s
+
+// RUN: %clang_cc1 -triple powerpc64-ibm-aix-xcoff -fdump-record-layouts \
+// RUN: -fsyntax-only %s | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK64 %s
+
+namespace test1 {
+struct A {
+  double d1;
+  virtual void boo() {}
+};
+
+struct B {
+  double d2;
+  A a;
+};
+
+struct C : public A {
+  double d3;
+};
+
+int i = sizeof(B);
+int j = sizeof(C);
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::A
+// CHECK-NEXT:0 |   (A vtable pointer)
+// CHECK32-NEXT:  4 |   double d1
+// CHECK32-NEXT:| [sizeof=12, dsize=12, align=4, preferredalign=4,
+// CHECK32-NEXT:|  nvsize=12, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:  8 |   double d1
+// CHECK64-NEXT:| [sizeof=16, dsize=16, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=16, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::B
+// CHECK-NEXT:0 |   double d2
+// CHECK-NEXT:8 |   struct test1::A a
+// CHECK-NEXT:8 | (A vtable pointer)
+// CHECK32-NEXT: 12 | double d1
+// CHECK32-NEXT:| [sizeof=24, dsize=20, align=4, preferredalign=8,
+// CHECK32-NEXT:|  nvsize=20, nvalign=4, preferrednvalign=8]
+// CHECK64-NEXT: 16 | double d1
+// CHECK64-NEXT:| [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=24, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::C
+// CHECK-NEXT:0 |   struct test1::A (primary base)
+// CHECK-NEXT:0 | (A vtable pointer)
+// CHECK32-NEXT:  4 | double d1
+// CHECK32-NEXT: 12 |   double d3
+// CHECK32-NEXT:| [sizeof=20, dsize=20, align=4, preferredalign=4,
+// CHECK32-NEXT:|  nvsize=20, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:  8 | double d1
+// CHECK64-NEXT: 16 |   double d3
+// CHECK64-NEXT:| [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=24, nvalign=8, preferrednvalign=8]
+
+} // namespace test1
+
+namespace test2 {
+struct A {
+  long long l1;
+};
+
+struct B : public virtual A {
+  double d2;
+};
+
+#pragma pack(2)
+struct C : public virtual A {
+  double __attribute__((aligned(4))) d3;
+};
+
+int i = sizeof(B);
+int j = sizeof(C);
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::A
+// CHECK-NEXT:0 |   long long l1
+// CHECK-NEXT:  | [sizeof=8, dsize=8, align=8, preferredalign=8,
+// CHECK-NEXT:  |  nvsize=8, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::B
+// CHECK-NEXT:0 |   (B vtable pointer)
+// CHECK32-NEXT:  4 |   double d2
+// CHECK64-NEXT:  8 |   double d2
+// CHECK-NEXT:   16 |   struct test2::A (virtual base)
+// CHECK-NEXT:   16 | long long l1
+// CHECK-NEXT:  | [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK32-NEXT:|  nvsize=12, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:|  nvsize=16, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::C
+// CHECK-NEXT:0 |   (C vtable pointer)
+// CHECK32-NEXT:  4 |   double d3
+// CHECK3

[PATCH] D84534: [AIX] Static init frontend recovery and backend support

2020-07-24 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L created this revision.
Xiangling_L added reviewers: jasonliu, hubert.reinterpretcast, yusra.syeda, 
zarko, xingxue.
Xiangling_L added a project: LLVM.
Herald added subscribers: llvm-commits, cfe-commits, jfb, kbarton, hiraditya, 
nemanjai.
Herald added a project: clang.

1. Frontend side
2. Recovered AIX static init frontend to use the linkage type and function 
names Clang chooses for sinit related function;
3. Removed the `GlobalUniqueModuleId` calculation and usage;
4. Adjusted the FE testcases accordingly;
5. Added one frontend testcase to demonstrate and validate separate 
initialization on AIX;

2. Backend side on the assembly path only
3. Set correct linkage and function names for sinit/sterm functions
4. Added testcases


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D84534

Files:
  clang/lib/CodeGen/CGDeclCXX.cpp
  clang/lib/CodeGen/CodeGenModule.h
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/test/CodeGenCXX/aix-static-init-debug-info.cpp
  clang/test/CodeGenCXX/aix-static-init-temp-spec-and-inline-var.cpp
  clang/test/CodeGenCXX/aix-static-init.cpp
  llvm/include/llvm/CodeGen/AsmPrinter.h
  llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
  llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
  llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
  llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
  llvm/test/CodeGen/PowerPC/aix-static-init-default-priority.ll
  llvm/test/CodeGen/PowerPC/aix-static-init-no-unique-module-id.ll
  llvm/test/CodeGen/PowerPC/aix-static-init-non-default-priority.ll

Index: llvm/test/CodeGen/PowerPC/aix-static-init-non-default-priority.ll
===
--- /dev/null
+++ llvm/test/CodeGen/PowerPC/aix-static-init-non-default-priority.ll
@@ -0,0 +1,10 @@
+; RUN: not llc -mtriple powerpc-ibm-aix-xcoff < %s 2>&1 | FileCheck %s
+; RUN: not llc -mtriple powerpc64-ibm-aix-xcoff < %s 2>&1 | FileCheck %s
+
+@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 655, void ()* @foo, i8* null }]
+
+define void @foo() {
+  ret void
+}
+
+// CHECK: LLVM ERROR: prioritized sinit and sterm functions are not yet supported
Index: llvm/test/CodeGen/PowerPC/aix-static-init-no-unique-module-id.ll
===
--- /dev/null
+++ llvm/test/CodeGen/PowerPC/aix-static-init-no-unique-module-id.ll
@@ -0,0 +1,7 @@
+; RUN: not llc -mtriple powerpc-ibm-aix-xcoff < %s 2>&1 | FileCheck %s
+; RUN: not llc -mtriple powerpc64-ibm-aix-xcoff < %s 2>&1 | FileCheck %s
+
+@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @foo, i8* null }]
+@llvm.global_dtors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @bar, i8* null }]
+
+// CHECK: LLVM ERROR: cannot produce a unique identifier for this module based on strong external symbols
Index: llvm/test/CodeGen/PowerPC/aix-static-init-default-priority.ll
===
--- /dev/null
+++ llvm/test/CodeGen/PowerPC/aix-static-init-default-priority.ll
@@ -0,0 +1,31 @@
+; RUN: llc -mtriple powerpc-ibm-aix-xcoff < %s | FileCheck %s
+; RUN: llc -mtriple powerpc64-ibm-aix-xcoff < %s | FileCheck %s
+
+@llvm.global_ctors = appending global [2 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @init1, i8* null }, { i32, void ()*, i8* } { i32 65535, void ()* @init2, i8* null }]
+@llvm.global_dtors = appending global [2 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @destruct1, i8* null }, { i32, void ()*, i8* } { i32 65535, void ()* @destruct2, i8* null }]
+
+define i32 @extFunc() {
+entry:
+  ret i32 3
+}
+
+define internal void @init1() {
+  ret void
+}
+
+define internal void @destruct1() {
+  ret void
+}
+
+define internal void @init2() {
+  ret void
+}
+
+define internal void @destruct2() {
+  ret void
+}
+
+; CHECK: .globl	.__sinit8000_clang_ac404299654d2af7eae71e75c17f7c9b_0
+; CHECK: .globl	.__sterm8000_clang_ac404299654d2af7eae71e75c17f7c9b_0
+; CHECK: .globl	.__sinit8000_clang_ac404299654d2af7eae71e75c17f7c9b_1
+; CHECK: .globl	.__sterm8000_clang_ac404299654d2af7eae71e75c17f7c9b_1
Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
===
--- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -67,6 +67,7 @@
 #include "llvm/Support/TargetRegistry.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Target/TargetMachine.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
 #include 
 #include 
 #include 
@@ -153,6 +154,9 @@
   /// linkage for them in AIX.
   SmallPtrSet ExtSymSDNodeSymbols;
 
+  /// A unique trailing identifier as a part of sinit/sterm functions.
+  std::string GlobalUniqueModuleId;
+
   static void ValidateGV(const GlobalVariable *GV);
   // Record a list of GlobalAlia

[PATCH] D84534: [AIX] Static init frontend recovery and backend support

2020-07-27 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L updated this revision to Diff 280897.
Xiangling_L added a comment.

Fix clang-tidy errors;


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D84534/new/

https://reviews.llvm.org/D84534

Files:
  clang/lib/CodeGen/CGDeclCXX.cpp
  clang/lib/CodeGen/CodeGenModule.h
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/test/CodeGenCXX/aix-static-init-debug-info.cpp
  clang/test/CodeGenCXX/aix-static-init-temp-spec-and-inline-var.cpp
  clang/test/CodeGenCXX/aix-static-init.cpp
  llvm/include/llvm/CodeGen/AsmPrinter.h
  llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
  llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
  llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
  llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
  llvm/test/CodeGen/PowerPC/aix-static-init-default-priority.ll
  llvm/test/CodeGen/PowerPC/aix-static-init-no-unique-module-id.ll
  llvm/test/CodeGen/PowerPC/aix-static-init-non-default-priority.ll

Index: llvm/test/CodeGen/PowerPC/aix-static-init-non-default-priority.ll
===
--- /dev/null
+++ llvm/test/CodeGen/PowerPC/aix-static-init-non-default-priority.ll
@@ -0,0 +1,10 @@
+; RUN: not llc -mtriple powerpc-ibm-aix-xcoff < %s 2>&1 | FileCheck %s
+; RUN: not llc -mtriple powerpc64-ibm-aix-xcoff < %s 2>&1 | FileCheck %s
+
+@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 655, void ()* @foo, i8* null }]
+
+define void @foo() {
+  ret void
+}
+
+// CHECK: LLVM ERROR: prioritized sinit and sterm functions are not yet supported
Index: llvm/test/CodeGen/PowerPC/aix-static-init-no-unique-module-id.ll
===
--- /dev/null
+++ llvm/test/CodeGen/PowerPC/aix-static-init-no-unique-module-id.ll
@@ -0,0 +1,7 @@
+; RUN: not llc -mtriple powerpc-ibm-aix-xcoff < %s 2>&1 | FileCheck %s
+; RUN: not llc -mtriple powerpc64-ibm-aix-xcoff < %s 2>&1 | FileCheck %s
+
+@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @foo, i8* null }]
+@llvm.global_dtors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @bar, i8* null }]
+
+// CHECK: LLVM ERROR: cannot produce a unique identifier for this module based on strong external symbols
Index: llvm/test/CodeGen/PowerPC/aix-static-init-default-priority.ll
===
--- /dev/null
+++ llvm/test/CodeGen/PowerPC/aix-static-init-default-priority.ll
@@ -0,0 +1,31 @@
+; RUN: llc -mtriple powerpc-ibm-aix-xcoff < %s | FileCheck %s
+; RUN: llc -mtriple powerpc64-ibm-aix-xcoff < %s | FileCheck %s
+
+@llvm.global_ctors = appending global [2 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @init1, i8* null }, { i32, void ()*, i8* } { i32 65535, void ()* @init2, i8* null }]
+@llvm.global_dtors = appending global [2 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @destruct1, i8* null }, { i32, void ()*, i8* } { i32 65535, void ()* @destruct2, i8* null }]
+
+define i32 @extFunc() {
+entry:
+  ret i32 3
+}
+
+define internal void @init1() {
+  ret void
+}
+
+define internal void @destruct1() {
+  ret void
+}
+
+define internal void @init2() {
+  ret void
+}
+
+define internal void @destruct2() {
+  ret void
+}
+
+; CHECK: .globl	.__sinit8000_clang_ac404299654d2af7eae71e75c17f7c9b_0
+; CHECK: .globl	.__sterm8000_clang_ac404299654d2af7eae71e75c17f7c9b_0
+; CHECK: .globl	.__sinit8000_clang_ac404299654d2af7eae71e75c17f7c9b_1
+; CHECK: .globl	.__sterm8000_clang_ac404299654d2af7eae71e75c17f7c9b_1
Index: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
===
--- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
+++ llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
@@ -67,6 +67,7 @@
 #include "llvm/Support/TargetRegistry.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Target/TargetMachine.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
 #include 
 #include 
 #include 
@@ -153,6 +154,9 @@
   /// linkage for them in AIX.
   SmallPtrSet ExtSymSDNodeSymbols;
 
+  /// A unique trailing identifier as a part of sinit/sterm functions.
+  std::string GlobalUniqueModuleId;
+
   static void ValidateGV(const GlobalVariable *GV);
   // Record a list of GlobalAlias associated with a GlobalObject.
   // This is used for AIX's extra-label-at-definition aliasing strategy.
@@ -171,6 +175,9 @@
 
   bool doInitialization(Module &M) override;
 
+  void emitXXStructor(const DataLayout &DL, const int Priority,
+  const unsigned Index, Constant *CV, bool IsCtor) override;
+
   void SetupMachineFunction(MachineFunction &MF) override;
 
   void emitGlobalVariable(const GlobalVariable *GV) override;
@@ -1687,10 +1694,7 @@
 void PPCAIXAsmPrinter::emitGlobalVariable(const GlobalVariable *GV) {
   ValidateGV(GV);
 
-  // TODO: Update the handling of global arrays for 

[PATCH] D79719: [AIX] Implement AIX special alignment rule about double/long double

2020-07-27 Thread Xiangling Liao via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG05ad8e942996: [AIX] Implement AIX special alignment rule 
about double/long double (authored by Xiangling_L).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79719/new/

https://reviews.llvm.org/D79719

Files:
  clang/include/clang/AST/RecordLayout.h
  clang/include/clang/Basic/TargetInfo.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/RecordLayout.cpp
  clang/lib/AST/RecordLayoutBuilder.cpp
  clang/lib/Basic/Targets/OSTargets.h
  clang/lib/Basic/Targets/PPC.h
  clang/test/Layout/aix-Wpacked-expecting-diagnostics.cpp
  clang/test/Layout/aix-Wpacked-no-diagnostics.cpp
  clang/test/Layout/aix-double-struct-member.cpp
  clang/test/Layout/aix-no-unique-address-with-double.cpp
  clang/test/Layout/aix-pack-attr-on-base.cpp
  clang/test/Layout/aix-power-alignment-typedef-2.cpp
  clang/test/Layout/aix-power-alignment-typedef.cpp
  clang/test/Layout/aix-virtual-function-and-base-with-double.cpp

Index: clang/test/Layout/aix-virtual-function-and-base-with-double.cpp
===
--- /dev/null
+++ clang/test/Layout/aix-virtual-function-and-base-with-double.cpp
@@ -0,0 +1,112 @@
+// RUN: %clang_cc1 -triple powerpc-ibm-aix-xcoff -fdump-record-layouts \
+// RUN: -fsyntax-only %s | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK32 %s
+
+// RUN: %clang_cc1 -triple powerpc64-ibm-aix-xcoff -fdump-record-layouts \
+// RUN: -fsyntax-only %s | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK64 %s
+
+namespace test1 {
+struct A {
+  double d1;
+  virtual void boo() {}
+};
+
+struct B {
+  double d2;
+  A a;
+};
+
+struct C : public A {
+  double d3;
+};
+
+int i = sizeof(B);
+int j = sizeof(C);
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::A
+// CHECK-NEXT:0 |   (A vtable pointer)
+// CHECK32-NEXT:  4 |   double d1
+// CHECK32-NEXT:| [sizeof=12, dsize=12, align=4, preferredalign=4,
+// CHECK32-NEXT:|  nvsize=12, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:  8 |   double d1
+// CHECK64-NEXT:| [sizeof=16, dsize=16, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=16, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::B
+// CHECK-NEXT:0 |   double d2
+// CHECK-NEXT:8 |   struct test1::A a
+// CHECK-NEXT:8 | (A vtable pointer)
+// CHECK32-NEXT: 12 | double d1
+// CHECK32-NEXT:| [sizeof=24, dsize=20, align=4, preferredalign=8,
+// CHECK32-NEXT:|  nvsize=20, nvalign=4, preferrednvalign=8]
+// CHECK64-NEXT: 16 | double d1
+// CHECK64-NEXT:| [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=24, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::C
+// CHECK-NEXT:0 |   struct test1::A (primary base)
+// CHECK-NEXT:0 | (A vtable pointer)
+// CHECK32-NEXT:  4 | double d1
+// CHECK32-NEXT: 12 |   double d3
+// CHECK32-NEXT:| [sizeof=20, dsize=20, align=4, preferredalign=4,
+// CHECK32-NEXT:|  nvsize=20, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:  8 | double d1
+// CHECK64-NEXT: 16 |   double d3
+// CHECK64-NEXT:| [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=24, nvalign=8, preferrednvalign=8]
+
+} // namespace test1
+
+namespace test2 {
+struct A {
+  long long l1;
+};
+
+struct B : public virtual A {
+  double d2;
+};
+
+#pragma pack(2)
+struct C : public virtual A {
+  double __attribute__((aligned(4))) d3;
+};
+
+int i = sizeof(B);
+int j = sizeof(C);
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::A
+// CHECK-NEXT:0 |   long long l1
+// CHECK-NEXT:  | [sizeof=8, dsize=8, align=8, preferredalign=8,
+// CHECK-NEXT:  |  nvsize=8, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::B
+// CHECK-NEXT:0 |   (B vtable pointer)
+// CHECK32-NEXT:  4 |   double d2
+// CHECK64-NEXT:  8 |   double d2
+// CHECK-NEXT:   16 |   struct test2::A (virtual base)
+// CHECK-NEXT:   16 | long long l1
+// CHECK-NEXT:  | [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK32-NEXT:|  nvsize=12, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:|  nvsize=16, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::C
+// CHECK-NEXT:0 |   (C vtable pointer)
+// CHECK32-NEXT:  4 | 

[PATCH] D84534: [AIX] Static init frontend recovery and backend support

2020-07-28 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L marked 5 inline comments as done.
Xiangling_L added inline comments.



Comment at: clang/lib/CodeGen/ItaniumCXXABI.cpp:4609
+// their own llvm.global_dtors entry.
+CGM.AddCXXStermFinalizerToGlobalDtor(StermFinalizer, 65535);
+  else

jasonliu wrote:
> Handling template instantiation seems fairly orthogonal to "moving naming 
> logic from frontend to backend". Could we put it in a separate patch (which 
> could be a child of this one)? 
The reason I chose to handle template instantiation and inline variable in this 
patch is that I want to show the scenarios where we have separate 
initialization. And this is also the reason why we want to embed array index 
into sinit/sterm functions. That is, if we move this part into a separate 
patch, I am worried that ppl will feel it's weird to embed index into function 
names.



Comment at: llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp:2165
+  emitXXStructor(DL, S.Priority, index, S.Func, isCtor);
+  ++index;
+  continue;

jasonliu wrote:
> Maybe a naive quesiton, in what situation would we have name collision and 
> need `index` as suffix to differentiate?
> Could we just report_fatal_error in those situation?
As far as I know, there are several situations we would have separate 
initialization without considering priority:
1) template specialization
2) inline variable
3) ctor/dtor attribute functions

By embedding the index, we can group those sinit/sterm with same priority 
within current file together.

And as I mentioned above, I chose to handle the former two cases in this patch 
to show why we need to embed the index.

And regarding the third scenario, we've already report_fatal_error on those 
cases.



Comment at: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1848
+// beforing emitting them.
+if (isSpecialLLVMGlobalArrayForStaticInit(&G)) {
+  if (GlobalUniqueModuleId.empty()) {

jasonliu wrote:
> This would have conflict with D84363. You might want to rebase it later. 
Thanks for the reminder, I will update the patch accordingly.



Comment at: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1935
+  Function *Func = cast(CV);
+  Func->setLinkage(GlobalValue::ExternalLinkage);
+  Func->setName((isCtor ? llvm::Twine("__sinit") : llvm::Twine("__sterm")) +

jasonliu wrote:
> Changing Function name and linkage underneath looks a bit scary. People would 
> have a hard time to map IR to final assembly that gets produced. Have you 
> thought about creating an alias (with the correct linkage and name) to the 
> original function instead?
Good point. I will adjust the implementation here.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D84534/new/

https://reviews.llvm.org/D84534

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D84534: [AIX] Static init frontend recovery and backend support

2020-07-28 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L updated this revision to Diff 281240.
Xiangling_L marked 4 inline comments as done.
Xiangling_L added a comment.

Created alias for sinit and sterm;
Adjusted the testcase accordingly;


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D84534/new/

https://reviews.llvm.org/D84534

Files:
  clang/lib/CodeGen/CGDeclCXX.cpp
  clang/lib/CodeGen/CodeGenModule.h
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/test/CodeGenCXX/aix-static-init-debug-info.cpp
  clang/test/CodeGenCXX/aix-static-init-temp-spec-and-inline-var.cpp
  clang/test/CodeGenCXX/aix-static-init.cpp
  llvm/include/llvm/CodeGen/AsmPrinter.h
  llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
  llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
  llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
  llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
  llvm/test/CodeGen/PowerPC/aix-static-init-default-priority.ll
  llvm/test/CodeGen/PowerPC/aix-static-init-no-unique-module-id.ll
  llvm/test/CodeGen/PowerPC/aix-static-init-non-default-priority.ll

Index: llvm/test/CodeGen/PowerPC/aix-static-init-non-default-priority.ll
===
--- /dev/null
+++ llvm/test/CodeGen/PowerPC/aix-static-init-non-default-priority.ll
@@ -0,0 +1,10 @@
+; RUN: not llc -mtriple powerpc-ibm-aix-xcoff < %s 2>&1 | FileCheck %s
+; RUN: not llc -mtriple powerpc64-ibm-aix-xcoff < %s 2>&1 | FileCheck %s
+
+@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 655, void ()* @foo, i8* null }]
+
+define void @foo() {
+  ret void
+}
+
+// CHECK: LLVM ERROR: prioritized sinit and sterm functions are not yet supported
Index: llvm/test/CodeGen/PowerPC/aix-static-init-no-unique-module-id.ll
===
--- /dev/null
+++ llvm/test/CodeGen/PowerPC/aix-static-init-no-unique-module-id.ll
@@ -0,0 +1,7 @@
+; RUN: not llc -mtriple powerpc-ibm-aix-xcoff < %s 2>&1 | FileCheck %s
+; RUN: not llc -mtriple powerpc64-ibm-aix-xcoff < %s 2>&1 | FileCheck %s
+
+@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @foo, i8* null }]
+@llvm.global_dtors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @bar, i8* null }]
+
+// CHECK: LLVM ERROR: cannot produce a unique identifier for this module based on strong external symbols
Index: llvm/test/CodeGen/PowerPC/aix-static-init-default-priority.ll
===
--- /dev/null
+++ llvm/test/CodeGen/PowerPC/aix-static-init-default-priority.ll
@@ -0,0 +1,60 @@
+; RUN: llc -mtriple powerpc-ibm-aix-xcoff < %s | FileCheck %s
+; RUN: llc -mtriple powerpc64-ibm-aix-xcoff < %s | FileCheck %s
+
+@llvm.global_ctors = appending global [2 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @init1, i8* null }, { i32, void ()*, i8* } { i32 65535, void ()* @init2, i8* null }]
+@llvm.global_dtors = appending global [2 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @destruct1, i8* null }, { i32, void ()*, i8* } { i32 65535, void ()* @destruct2, i8* null }]
+
+define i32 @extFunc() {
+entry:
+  ret i32 3
+}
+
+define internal void @init1() {
+  ret void
+}
+
+define internal void @destruct1() {
+  ret void
+}
+
+define internal void @init2() {
+  ret void
+}
+
+define internal void @destruct2() {
+  ret void
+}
+
+; CHECK:   .lglobl	init1[DS]
+; CHECK:   .lglobl	.init1
+; CHECK:   .csect init1[DS]
+; CHECK: __sinit8000_clang_ac404299654d2af7eae71e75c17f7c9b_0: # @init1
+; CHECK: .init1:
+; CHECK: .__sinit8000_clang_ac404299654d2af7eae71e75c17f7c9b_0:
+; CHECK:   .lglobl	destruct1[DS]
+; CHECK:   .lglobl	.destruct1
+; CHECK:   .csect destruct1[DS]
+; CHECK: __sterm8000_clang_ac404299654d2af7eae71e75c17f7c9b_0: # @destruct1
+; CHECK: .destruct1:
+; CHECK: .__sterm8000_clang_ac404299654d2af7eae71e75c17f7c9b_0:
+; CHECK:   .lglobl	init2[DS]
+; CHECK:   .lglobl	.init2
+; CHECK:   .csect init2[DS]
+; CHECK: __sinit8000_clang_ac404299654d2af7eae71e75c17f7c9b_1: # @init2
+; CHECK: .init2:
+; CHECK: .__sinit8000_clang_ac404299654d2af7eae71e75c17f7c9b_1:
+; CHECK:   .lglobl	destruct2[DS]
+; CHECK:   .lglobl	.destruct2
+; CHECK:   .csect destruct2[DS]
+; CHECK: __sterm8000_clang_ac404299654d2af7eae71e75c17f7c9b_1: # @destruct2
+; CHECK: .destruct2:
+; CHECK: .__sterm8000_clang_ac404299654d2af7eae71e75c17f7c9b_1:
+
+; CHECK: 	.globl	__sinit8000_clang_ac404299654d2af7eae71e75c17f7c9b_0
+; CHECK: 	.globl	.__sinit8000_clang_ac404299654d2af7eae71e75c17f7c9b_0
+; CHECK: 	.globl	__sinit8000_clang_ac404299654d2af7eae71e75c17f7c9b_1
+; CHECK: 	.globl	.__sinit8000_clang_ac404299654d2af7eae71e75c17f7c9b_1
+; CHECK: 	.globl	__sterm8000_clang_ac404299654d2af7eae71e75c17f7c9b_0
+; CHECK: 	.globl	.__sterm8000_clang_ac404299654d2af7eae71e75c17f7c9b_0

[PATCH] D84880: [AIX] Temporarily disable IncrementalProcessingTest partially

2020-07-29 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L created this revision.
Xiangling_L added reviewers: daltenty, jasonliu, stevewan, 
hubert.reinterpretcast.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
Xiangling_L requested review of this revision.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D84880

Files:
  clang/unittests/CodeGen/IncrementalProcessingTest.cpp


Index: clang/unittests/CodeGen/IncrementalProcessingTest.cpp
===
--- clang/unittests/CodeGen/IncrementalProcessingTest.cpp
+++ clang/unittests/CodeGen/IncrementalProcessingTest.cpp
@@ -159,6 +159,11 @@
 // First code should not end up in second module:
 ASSERT_FALSE(M[2]->getFunction("funcForProg1"));
 
+// TODO: Remove this after the static initialization frontend 
implementation
+// is recovered on AIX.
+if (compiler.getTarget().getTriple().isOSAIX())
+  return;
+
 // Make sure global inits exist and are unique:
 const Function* GlobalInit1 = getGlobalInit(*M[1]);
 ASSERT_TRUE(GlobalInit1);


Index: clang/unittests/CodeGen/IncrementalProcessingTest.cpp
===
--- clang/unittests/CodeGen/IncrementalProcessingTest.cpp
+++ clang/unittests/CodeGen/IncrementalProcessingTest.cpp
@@ -159,6 +159,11 @@
 // First code should not end up in second module:
 ASSERT_FALSE(M[2]->getFunction("funcForProg1"));
 
+// TODO: Remove this after the static initialization frontend implementation
+// is recovered on AIX.
+if (compiler.getTarget().getTriple().isOSAIX())
+  return;
+
 // Make sure global inits exist and are unique:
 const Function* GlobalInit1 = getGlobalInit(*M[1]);
 ASSERT_TRUE(GlobalInit1);
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D84880: [AIX] Temporarily disable IncrementalProcessingTest partially

2020-07-30 Thread Xiangling Liao via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG4e6176fd912a: [AIX] Temporarily disable 
IncrementalProcessingTest partially (authored by Xiangling_L).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D84880/new/

https://reviews.llvm.org/D84880

Files:
  clang/unittests/CodeGen/IncrementalProcessingTest.cpp


Index: clang/unittests/CodeGen/IncrementalProcessingTest.cpp
===
--- clang/unittests/CodeGen/IncrementalProcessingTest.cpp
+++ clang/unittests/CodeGen/IncrementalProcessingTest.cpp
@@ -159,6 +159,11 @@
 // First code should not end up in second module:
 ASSERT_FALSE(M[2]->getFunction("funcForProg1"));
 
+// TODO: Remove this after the static initialization frontend 
implementation
+// is recovered on AIX.
+if (compiler.getTarget().getTriple().isOSAIX())
+  return;
+
 // Make sure global inits exist and are unique:
 const Function* GlobalInit1 = getGlobalInit(*M[1]);
 ASSERT_TRUE(GlobalInit1);


Index: clang/unittests/CodeGen/IncrementalProcessingTest.cpp
===
--- clang/unittests/CodeGen/IncrementalProcessingTest.cpp
+++ clang/unittests/CodeGen/IncrementalProcessingTest.cpp
@@ -159,6 +159,11 @@
 // First code should not end up in second module:
 ASSERT_FALSE(M[2]->getFunction("funcForProg1"));
 
+// TODO: Remove this after the static initialization frontend implementation
+// is recovered on AIX.
+if (compiler.getTarget().getTriple().isOSAIX())
+  return;
+
 // Make sure global inits exist and are unique:
 const Function* GlobalInit1 = getGlobalInit(*M[1]);
 ASSERT_TRUE(GlobalInit1);
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D84534: [AIX] Static init frontend recovery and backend support

2020-07-30 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L updated this revision to Diff 281938.
Xiangling_L added a comment.

Removed the disablement in IncrementalProcessingTest.cpp cross-target test;


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D84534/new/

https://reviews.llvm.org/D84534

Files:
  clang/lib/CodeGen/CGDeclCXX.cpp
  clang/lib/CodeGen/CodeGenModule.h
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/test/CodeGenCXX/aix-static-init-debug-info.cpp
  clang/test/CodeGenCXX/aix-static-init-temp-spec-and-inline-var.cpp
  clang/test/CodeGenCXX/aix-static-init.cpp
  clang/unittests/CodeGen/IncrementalProcessingTest.cpp
  llvm/include/llvm/CodeGen/AsmPrinter.h
  llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
  llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
  llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
  llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
  llvm/test/CodeGen/PowerPC/aix-static-init-default-priority.ll
  llvm/test/CodeGen/PowerPC/aix-static-init-no-unique-module-id.ll
  llvm/test/CodeGen/PowerPC/aix-static-init-non-default-priority.ll

Index: llvm/test/CodeGen/PowerPC/aix-static-init-non-default-priority.ll
===
--- /dev/null
+++ llvm/test/CodeGen/PowerPC/aix-static-init-non-default-priority.ll
@@ -0,0 +1,10 @@
+; RUN: not llc -mtriple powerpc-ibm-aix-xcoff < %s 2>&1 | FileCheck %s
+; RUN: not llc -mtriple powerpc64-ibm-aix-xcoff < %s 2>&1 | FileCheck %s
+
+@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 655, void ()* @foo, i8* null }]
+
+define void @foo() {
+  ret void
+}
+
+// CHECK: LLVM ERROR: prioritized sinit and sterm functions are not yet supported
Index: llvm/test/CodeGen/PowerPC/aix-static-init-no-unique-module-id.ll
===
--- /dev/null
+++ llvm/test/CodeGen/PowerPC/aix-static-init-no-unique-module-id.ll
@@ -0,0 +1,7 @@
+; RUN: not llc -mtriple powerpc-ibm-aix-xcoff < %s 2>&1 | FileCheck %s
+; RUN: not llc -mtriple powerpc64-ibm-aix-xcoff < %s 2>&1 | FileCheck %s
+
+@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @foo, i8* null }]
+@llvm.global_dtors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @bar, i8* null }]
+
+// CHECK: LLVM ERROR: cannot produce a unique identifier for this module based on strong external symbols
Index: llvm/test/CodeGen/PowerPC/aix-static-init-default-priority.ll
===
--- /dev/null
+++ llvm/test/CodeGen/PowerPC/aix-static-init-default-priority.ll
@@ -0,0 +1,60 @@
+; RUN: llc -mtriple powerpc-ibm-aix-xcoff < %s | FileCheck %s
+; RUN: llc -mtriple powerpc64-ibm-aix-xcoff < %s | FileCheck %s
+
+@llvm.global_ctors = appending global [2 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @init1, i8* null }, { i32, void ()*, i8* } { i32 65535, void ()* @init2, i8* null }]
+@llvm.global_dtors = appending global [2 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @destruct1, i8* null }, { i32, void ()*, i8* } { i32 65535, void ()* @destruct2, i8* null }]
+
+define i32 @extFunc() {
+entry:
+  ret i32 3
+}
+
+define internal void @init1() {
+  ret void
+}
+
+define internal void @destruct1() {
+  ret void
+}
+
+define internal void @init2() {
+  ret void
+}
+
+define internal void @destruct2() {
+  ret void
+}
+
+; CHECK:   .lglobl	init1[DS]
+; CHECK:   .lglobl	.init1
+; CHECK:   .csect init1[DS]
+; CHECK: __sinit8000_clang_ac404299654d2af7eae71e75c17f7c9b_0: # @init1
+; CHECK: .init1:
+; CHECK: .__sinit8000_clang_ac404299654d2af7eae71e75c17f7c9b_0:
+; CHECK:   .lglobl	destruct1[DS]
+; CHECK:   .lglobl	.destruct1
+; CHECK:   .csect destruct1[DS]
+; CHECK: __sterm8000_clang_ac404299654d2af7eae71e75c17f7c9b_0: # @destruct1
+; CHECK: .destruct1:
+; CHECK: .__sterm8000_clang_ac404299654d2af7eae71e75c17f7c9b_0:
+; CHECK:   .lglobl	init2[DS]
+; CHECK:   .lglobl	.init2
+; CHECK:   .csect init2[DS]
+; CHECK: __sinit8000_clang_ac404299654d2af7eae71e75c17f7c9b_1: # @init2
+; CHECK: .init2:
+; CHECK: .__sinit8000_clang_ac404299654d2af7eae71e75c17f7c9b_1:
+; CHECK:   .lglobl	destruct2[DS]
+; CHECK:   .lglobl	.destruct2
+; CHECK:   .csect destruct2[DS]
+; CHECK: __sterm8000_clang_ac404299654d2af7eae71e75c17f7c9b_1: # @destruct2
+; CHECK: .destruct2:
+; CHECK: .__sterm8000_clang_ac404299654d2af7eae71e75c17f7c9b_1:
+
+; CHECK: 	.globl	__sinit8000_clang_ac404299654d2af7eae71e75c17f7c9b_0
+; CHECK: 	.globl	.__sinit8000_clang_ac404299654d2af7eae71e75c17f7c9b_0
+; CHECK: 	.globl	__sinit8000_clang_ac404299654d2af7eae71e75c17f7c9b_1
+; CHECK: 	.globl	.__sinit8000_clang_ac404299654d2af7eae71e75c17f7c9b_1
+; CHECK: 	.globl	__sterm8000_clang_ac404299654d2af7eae71e75c17f7c9b_0
+; CHECK: 	.globl	.__sterm8000_clang_ac404299654d2af7eae

[PATCH] D76360: [PPC][AIX] Emit correct Vaarg for 32BIT-AIX in clang

2020-04-06 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L added inline comments.



Comment at: clang/test/CodeGen/aix-vararg.c:15
+
+  // 32BIT:   define void @aix_varg(i32 %a, ...) #0 {
+  // 32BIT-NEXT:  entry:

`#0`, `#1`[the last three lines] are redundant, could you clean them up?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D76360/new/

https://reviews.llvm.org/D76360



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D74166: [AIX][Frontend] Static init implementation for AIX considering no priority

2020-04-06 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L updated this revision to Diff 255456.
Xiangling_L added a comment.

Rebase on the latest master branch;


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D74166/new/

https://reviews.llvm.org/D74166

Files:
  clang/include/clang/AST/Mangle.h
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/CodeGen/CGCXXABI.h
  clang/lib/CodeGen/CGDeclCXX.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/CodeGen/CodeGenModule.h
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/CodeGen/aix-priority-attribute.cpp
  clang/test/CodeGen/static-init.cpp

Index: clang/test/CodeGen/static-init.cpp
===
--- clang/test/CodeGen/static-init.cpp
+++ clang/test/CodeGen/static-init.cpp
@@ -1,12 +1,55 @@
-// RUN: not %clang_cc1 -triple powerpc-ibm-aix-xcoff -S -emit-llvm -x c++ %s \
-// RUN: -o /dev/null 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -triple powerpc-ibm-aix-xcoff -S -emit-llvm -x c++ < %s \
+// RUN: | FileCheck %s
 
-// RUN: not %clang_cc1 -triple powerpc64-ibm-aix-xcoff -S -emit-llvm -x c++ %s \
-// RUN: -o /dev/null 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -triple powerpc64-ibm-aix-xcoff -S -emit-llvm -x c++ < %s \
+// RUN: | FileCheck %s
 
 struct test {
   test();
   ~test();
 } t;
 
-// CHECK: error in backend: Static initialization has not been implemented on XL ABI yet.
+// CHECK: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @__sinit8000_clang_b2e4830f1c9d2d063e5ea946868f3bfd, i8* null }]
+// CHECK: @llvm.global_dtors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @__sterm8000_clang_b2e4830f1c9d2d063e5ea946868f3bfd, i8* null }]
+// CHECK: define dso_local void @__cxx_global_var_init() #0 {
+// CHECK: entry:
+// CHECK:   call void @_ZN4testC1Ev(%struct.test* @t)
+// CHECK:   %0 = call i32 @atexit(void ()* @__dtor_t)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define dso_local void @__dtor_t() #0 {
+// CHECK: entry:
+// CHECK:   call void @_ZN4testD1Ev(%struct.test* @t)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: declare i32 @atexit(void ()*) #3
+
+// CHECK: define dso_local void @__cxx_global_var_destruct_t() #0 {
+// CHECK: entry:
+// CHECK:   %0 = call i32 @unatexit(void ()* @__dtor_t)
+// CHECK:   %guard.hasSrterm = icmp eq i32 %0, 0
+// CHECK:   br i1 %guard.hasSrterm, label %destruct.check, label %destruct.end
+
+// CHECK: destruct.check:
+// CHECK:   call void @__dtor_t()
+// CHECK:   br label %destruct.end
+
+// CHECK: destruct.end:
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: declare i32 @unatexit(void ()*) #3
+
+// CHECK: define dso_local void @__sinit8000_clang_b2e4830f1c9d2d063e5ea946868f3bfd() #0 {
+// CHECK: entry:
+// CHECK:   call void @__cxx_global_var_init()
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define dso_local void @__sterm8000_clang_b2e4830f1c9d2d063e5ea946868f3bfd() #0 {
+// CHECK: entry:
+// CHECK:   call void @__cxx_global_var_destruct_t()
+// CHECK:   ret void
+// CHECK: }
Index: clang/test/CodeGen/aix-priority-attribute.cpp
===
--- /dev/null
+++ clang/test/CodeGen/aix-priority-attribute.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple powerpc-ibm-aix-xcoff -x c++ -emit-llvm < %s 2>&1 | \
+// RUN: FileCheck %s
+// RUN: %clang_cc1 -triple powerpc64-ibm-aix-xcoff -x c++ -emit-llvm < %s 2>&1 | \
+// RUN: FileCheck %s
+
+int foo() __attribute__((constructor(180)));
+int bar() __attribute__((destructor(180)));
+
+class test {
+   int a;
+public:
+test(int c) {a = c;}
+~test() {a = 0;}
+};
+
+__attribute__ ((init_priority (2000)))
+test t(1);
+
+// CHECK: warning: 'constructor' attribute argument not supported:
+// CHECK: int foo() __attribute__((constructor(180)));
+
+// CHECK: warning: 'destructor' attribute argument not supported:
+// check: int bar() __attribute__((destructor(180)));
+
+// CHECK: warning: 'init_priority' attribute argument not supported:
+// CHECK: __attribute__ ((init_priority (2000)))
Index: clang/lib/Sema/SemaDeclAttr.cpp
===
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -6876,13 +6876,19 @@
 handlePassObjectSizeAttr(S, D, AL);
 break;
   case ParsedAttr::AT_Constructor:
-handleConstructorAttr(S, D, AL);
+if (S.Context.getTargetInfo().getTriple().isOSAIX())
+  S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported) << AL << "";
+else
+  handleConstructorAttr(S, D, AL);
 break;
   case ParsedAttr::AT_Deprecated:
 handleDeprecatedAttr(S, D, AL);
 break;
   case ParsedAttr::AT_Destructor:
-handleDestructorAttr(S, D, AL);
+if (S.Context.getTargetInfo().getTriple().isOSAIX())
+  S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported) << AL << "";
+else
+  h

[PATCH] D76360: [PPC][AIX] Emit correct Vaarg for 32BIT-AIX in clang

2020-04-06 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L added inline comments.



Comment at: clang/lib/CodeGen/TargetInfo.cpp:4205
+
+class PPCAIX32TargetCodeGenInfo : public TargetCodeGenInfo {
+public:

I have a question here. AIX32 falls into PPC32 target, so why we don't inherit 
from `PPC32TargetCodeGenInfo` instead?



Comment at: clang/lib/CodeGen/TargetInfo.cpp:4210
+
+  int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const override {
+return 1; // r1 is the dedicated stack pointer

Is `getDwarfEHStackPointer` necessary to be correct for vararg of AIX to work[I 
guess possibly not]? If not, should it fall into Dwarf related patch rather 
than in this one? BTW, if your `PPCAIX32TargetCodeGenInfo` inherits from 
`PPC32TargetCodeGenInfo` instead as I mentioned above, then it would be 
naturally correct.



Comment at: clang/lib/CodeGen/TargetInfo.cpp:4447
+CodeGen::CodeGenFunction &CGF, llvm::Value *Address) const {
+  return true;
+}

As simple as this function is, does it make sense to move the body of `return 
true` into the class definition?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D76360/new/

https://reviews.llvm.org/D76360



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D76360: [PPC][AIX] Emit correct Vaarg for 32BIT-AIX in clang

2020-04-09 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L added inline comments.



Comment at: clang/lib/CodeGen/TargetInfo.cpp:4205
+
+class PPCAIX32TargetCodeGenInfo : public TargetCodeGenInfo {
+public:

sfertile wrote:
> Xiangling_L wrote:
> > I have a question here. AIX32 falls into PPC32 target, so why we don't 
> > inherit from `PPC32TargetCodeGenInfo` instead?
> Do we need a separate AIX specific class? We are implementing 2 functions, 1 
> of which is the same implementation as its `PPC32TargetCodeGenInfo` 
> counterpart. If we have access to the triple, we can  return true when the OS 
> is AIX in `PPC32TargetCodeGenInfo::initDwarfEHRegSizeTable`. With the 
> implementations being nearly identical (and after enabling 
> DwarfEHRegSizeTable they will be identical) I think we are better to not add 
> a new class if we can avoid it.
Not adding a new class makes sense to me if we are sure that 
`DwarfEHRegSizeTable` will be identical/viable for AIX.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D76360/new/

https://reviews.llvm.org/D76360



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D79719: [AIX] Implement AIX special alignment rule about double/long double

2020-06-04 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L updated this revision to Diff 268624.
Xiangling_L marked 11 inline comments as done.
Xiangling_L added a comment.

Add `PreferredAlignment` and `PreferredNVAlignment` field;
Adjust `-fdump-record-layouts` format for AIX;
Update the testcase formatting;


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79719/new/

https://reviews.llvm.org/D79719

Files:
  clang/include/clang/AST/RecordLayout.h
  clang/include/clang/Basic/TargetInfo.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/RecordLayout.cpp
  clang/lib/AST/RecordLayoutBuilder.cpp
  clang/lib/Basic/Targets/OSTargets.h
  clang/lib/Basic/Targets/PPC.h
  clang/test/Layout/aix-double-struct-member.cpp
  clang/test/Layout/aix-no-unique-address-with-double.cpp
  clang/test/Layout/aix-virtual-function-and-base-with-double.cpp

Index: clang/test/Layout/aix-virtual-function-and-base-with-double.cpp
===
--- /dev/null
+++ clang/test/Layout/aix-virtual-function-and-base-with-double.cpp
@@ -0,0 +1,112 @@
+// RUN: %clang_cc1 -emit-llvm-only -triple powerpc-ibm-aix-xcoff \
+// RUN: -fdump-record-layouts -fsyntax-only %s 2>/dev/null | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK32 %s
+
+// RUN: %clang_cc1 -emit-llvm-only -triple powerpc64-ibm-aix-xcoff \
+// RUN: -fdump-record-layouts -fsyntax-only %s 2>/dev/null | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK64 %s
+
+namespace test1 {
+struct A {
+  double d1;
+  virtual void boo() {}
+};
+
+struct B {
+  double d2;
+  A a;
+};
+
+struct C : public A {
+  double d3;
+};
+
+int i = sizeof(B);
+int j = sizeof(C);
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::A
+// CHECK-NEXT:0 |   (A vtable pointer)
+// CHECK32-NEXT:  4 |   double d1
+// CHECK32-NEXT:| [sizeof=12, dsize=12, align=4, preferredalign=4,
+// CHECK32-NEXT:|  nvsize=12, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:  8 |   double d1
+// CHECK64-NEXT:| [sizeof=16, dsize=16, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=16, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::B
+// CHECK-NEXT:0 |   double d2
+// CHECK-NEXT:8 |   struct test1::A a
+// CHECK-NEXT:8 | (A vtable pointer)
+// CHECK32-NEXT: 12 | double d1
+// CHECK32-NEXT:| [sizeof=24, dsize=20, align=4, preferredalign=8,
+// CHECK32-NEXT:|  nvsize=20, nvalign=4, preferrednvalign=8]
+// CHECK64-NEXT: 16 | double d1
+// CHECK64-NEXT:| [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=24, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::C
+// CHECK-NEXT:0 |   struct test1::A (primary base)
+// CHECK-NEXT:0 | (A vtable pointer)
+// CHECK32-NEXT:  4 | double d1
+// CHECK32-NEXT: 12 |   double d3
+// CHECK32-NEXT:| [sizeof=20, dsize=20, align=4, preferredalign=4,
+// CHECK32-NEXT:|  nvsize=20, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:  8 | double d1
+// CHECK64-NEXT: 16 |   double d3
+// CHECK64-NEXT:| [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=24, nvalign=8, preferrednvalign=8]
+
+}; // namespace test1
+
+namespace test2 {
+struct A {
+  long long l1;
+};
+
+struct B : public virtual A {
+  double d2;
+};
+
+#pragma pack(2)
+struct C : public virtual A {
+  double __attribute__((aligned(4))) d3;
+};
+
+int i = sizeof(B);
+int j = sizeof(C);
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::A
+// CHECK-NEXT:0 |   long long l1
+// CHECK-NEXT:  | [sizeof=8, dsize=8, align=8, preferredalign=8,
+// CHECK-NEXT:  |  nvsize=8, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::B
+// CHECK-NEXT:0 |   (B vtable pointer)
+// CHECK32-NEXT:  4 |   double d2
+// CHECK64-NEXT:  8 |   double d2
+// CHECK-NEXT:   16 |   struct test2::A (virtual base)
+// CHECK-NEXT:   16 | long long l1
+// CHECK-NEXT:  | [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK32-NEXT:|  nvsize=12, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:|  nvsize=16, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::C
+// CHECK-NEXT:0 |   (C vtable pointer)
+// CHECK32-NEXT:  4 |   double d3
+// CHECK32-NEXT: 12 |   struct test2::A (virtual base)
+// CHECK32-NEXT: 12 | long long l1
+// CHECK32-NEXT:

[PATCH] D79719: [AIX] Implement AIX special alignment rule about double/long double

2020-06-04 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L added inline comments.



Comment at: clang/lib/AST/ASTContext.cpp:2506
 
   if (!Target->allowsLargerPreferedTypeAlignment())
 return ABIAlign;

jyknight wrote:
> I think from here on down is currently X86-specific, even though it's not 
> phrased that way right now.
> 
> It only applies if this target hook doesn't disable it, and if alignof(X) < 
> sizeof(X), for X in {double, long long, unsigned long long}. It would be good 
> to try to determine if there's any other platforms for which those conditions 
> actually exist today, other than x86-32. And then determine if this code 
> block actually _should_ trigger there. (I suspect not.) Then, mark this stuff 
> as truthfully completely-target-specific, instead of pretending otherwise, as 
> we do now.
> 
Thank you for your suggestion. I think currently, there are three targets 
disabling this query, `XCore`, `X86` and `MSP430`. Since @efriedma mentioned we 
tried to avoid OS-specific checks here, I am not sure if mark this 
`completely-target-specific` is a good idea?  Personally, I think a query like 
`allowsLargerPreferedTypeAlignment()` would give more semantic meaning.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79719/new/

https://reviews.llvm.org/D79719



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D79719: [AIX] Implement AIX special alignment rule about double/long double

2020-06-05 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L updated this revision to Diff 268840.
Xiangling_L added a comment.

Replace `int` with an more self-explanatory enum;


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79719/new/

https://reviews.llvm.org/D79719

Files:
  clang/include/clang/AST/RecordLayout.h
  clang/include/clang/Basic/TargetInfo.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/RecordLayout.cpp
  clang/lib/AST/RecordLayoutBuilder.cpp
  clang/lib/Basic/Targets/OSTargets.h
  clang/lib/Basic/Targets/PPC.h
  clang/test/Layout/aix-double-struct-member.cpp
  clang/test/Layout/aix-no-unique-address-with-double.cpp
  clang/test/Layout/aix-virtual-function-and-base-with-double.cpp

Index: clang/test/Layout/aix-virtual-function-and-base-with-double.cpp
===
--- /dev/null
+++ clang/test/Layout/aix-virtual-function-and-base-with-double.cpp
@@ -0,0 +1,112 @@
+// RUN: %clang_cc1 -emit-llvm-only -triple powerpc-ibm-aix-xcoff \
+// RUN: -fdump-record-layouts -fsyntax-only %s 2>/dev/null | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK32 %s
+
+// RUN: %clang_cc1 -emit-llvm-only -triple powerpc64-ibm-aix-xcoff \
+// RUN: -fdump-record-layouts -fsyntax-only %s 2>/dev/null | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK64 %s
+
+namespace test1 {
+struct A {
+  double d1;
+  virtual void boo() {}
+};
+
+struct B {
+  double d2;
+  A a;
+};
+
+struct C : public A {
+  double d3;
+};
+
+int i = sizeof(B);
+int j = sizeof(C);
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::A
+// CHECK-NEXT:0 |   (A vtable pointer)
+// CHECK32-NEXT:  4 |   double d1
+// CHECK32-NEXT:| [sizeof=12, dsize=12, align=4, preferredalign=4,
+// CHECK32-NEXT:|  nvsize=12, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:  8 |   double d1
+// CHECK64-NEXT:| [sizeof=16, dsize=16, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=16, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::B
+// CHECK-NEXT:0 |   double d2
+// CHECK-NEXT:8 |   struct test1::A a
+// CHECK-NEXT:8 | (A vtable pointer)
+// CHECK32-NEXT: 12 | double d1
+// CHECK32-NEXT:| [sizeof=24, dsize=20, align=4, preferredalign=8,
+// CHECK32-NEXT:|  nvsize=20, nvalign=4, preferrednvalign=8]
+// CHECK64-NEXT: 16 | double d1
+// CHECK64-NEXT:| [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=24, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::C
+// CHECK-NEXT:0 |   struct test1::A (primary base)
+// CHECK-NEXT:0 | (A vtable pointer)
+// CHECK32-NEXT:  4 | double d1
+// CHECK32-NEXT: 12 |   double d3
+// CHECK32-NEXT:| [sizeof=20, dsize=20, align=4, preferredalign=4,
+// CHECK32-NEXT:|  nvsize=20, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:  8 | double d1
+// CHECK64-NEXT: 16 |   double d3
+// CHECK64-NEXT:| [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=24, nvalign=8, preferrednvalign=8]
+
+}; // namespace test1
+
+namespace test2 {
+struct A {
+  long long l1;
+};
+
+struct B : public virtual A {
+  double d2;
+};
+
+#pragma pack(2)
+struct C : public virtual A {
+  double __attribute__((aligned(4))) d3;
+};
+
+int i = sizeof(B);
+int j = sizeof(C);
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::A
+// CHECK-NEXT:0 |   long long l1
+// CHECK-NEXT:  | [sizeof=8, dsize=8, align=8, preferredalign=8,
+// CHECK-NEXT:  |  nvsize=8, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::B
+// CHECK-NEXT:0 |   (B vtable pointer)
+// CHECK32-NEXT:  4 |   double d2
+// CHECK64-NEXT:  8 |   double d2
+// CHECK-NEXT:   16 |   struct test2::A (virtual base)
+// CHECK-NEXT:   16 | long long l1
+// CHECK-NEXT:  | [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK32-NEXT:|  nvsize=12, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:|  nvsize=16, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::C
+// CHECK-NEXT:0 |   (C vtable pointer)
+// CHECK32-NEXT:  4 |   double d3
+// CHECK32-NEXT: 12 |   struct test2::A (virtual base)
+// CHECK32-NEXT: 12 | long long l1
+// CHECK32-NEXT:| [sizeof=20, dsize=20, align=2, preferredalign=2,
+// CHECK32-NEXT:|  nvsize=12, nvalign=2, preferrednvalign=2

[PATCH] D79719: [AIX] Implement AIX special alignment rule about double/long double

2020-06-08 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L updated this revision to Diff 269396.
Xiangling_L marked 2 inline comments as done.
Xiangling_L added a comment.

Simplify the code;
Add one more testcase related to [[no_unique_addr]];


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79719/new/

https://reviews.llvm.org/D79719

Files:
  clang/include/clang/AST/RecordLayout.h
  clang/include/clang/Basic/TargetInfo.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/RecordLayout.cpp
  clang/lib/AST/RecordLayoutBuilder.cpp
  clang/lib/Basic/Targets/OSTargets.h
  clang/lib/Basic/Targets/PPC.h
  clang/test/Layout/aix-double-struct-member.cpp
  clang/test/Layout/aix-no-unique-address-with-double.cpp
  clang/test/Layout/aix-virtual-function-and-base-with-double.cpp

Index: clang/test/Layout/aix-virtual-function-and-base-with-double.cpp
===
--- /dev/null
+++ clang/test/Layout/aix-virtual-function-and-base-with-double.cpp
@@ -0,0 +1,112 @@
+// RUN: %clang_cc1 -emit-llvm-only -triple powerpc-ibm-aix-xcoff \
+// RUN: -fdump-record-layouts -fsyntax-only %s 2>/dev/null | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK32 %s
+
+// RUN: %clang_cc1 -emit-llvm-only -triple powerpc64-ibm-aix-xcoff \
+// RUN: -fdump-record-layouts -fsyntax-only %s 2>/dev/null | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK64 %s
+
+namespace test1 {
+struct A {
+  double d1;
+  virtual void boo() {}
+};
+
+struct B {
+  double d2;
+  A a;
+};
+
+struct C : public A {
+  double d3;
+};
+
+int i = sizeof(B);
+int j = sizeof(C);
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::A
+// CHECK-NEXT:0 |   (A vtable pointer)
+// CHECK32-NEXT:  4 |   double d1
+// CHECK32-NEXT:| [sizeof=12, dsize=12, align=4, preferredalign=4,
+// CHECK32-NEXT:|  nvsize=12, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:  8 |   double d1
+// CHECK64-NEXT:| [sizeof=16, dsize=16, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=16, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::B
+// CHECK-NEXT:0 |   double d2
+// CHECK-NEXT:8 |   struct test1::A a
+// CHECK-NEXT:8 | (A vtable pointer)
+// CHECK32-NEXT: 12 | double d1
+// CHECK32-NEXT:| [sizeof=24, dsize=20, align=4, preferredalign=8,
+// CHECK32-NEXT:|  nvsize=20, nvalign=4, preferrednvalign=8]
+// CHECK64-NEXT: 16 | double d1
+// CHECK64-NEXT:| [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=24, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::C
+// CHECK-NEXT:0 |   struct test1::A (primary base)
+// CHECK-NEXT:0 | (A vtable pointer)
+// CHECK32-NEXT:  4 | double d1
+// CHECK32-NEXT: 12 |   double d3
+// CHECK32-NEXT:| [sizeof=20, dsize=20, align=4, preferredalign=4,
+// CHECK32-NEXT:|  nvsize=20, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:  8 | double d1
+// CHECK64-NEXT: 16 |   double d3
+// CHECK64-NEXT:| [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=24, nvalign=8, preferrednvalign=8]
+
+}; // namespace test1
+
+namespace test2 {
+struct A {
+  long long l1;
+};
+
+struct B : public virtual A {
+  double d2;
+};
+
+#pragma pack(2)
+struct C : public virtual A {
+  double __attribute__((aligned(4))) d3;
+};
+
+int i = sizeof(B);
+int j = sizeof(C);
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::A
+// CHECK-NEXT:0 |   long long l1
+// CHECK-NEXT:  | [sizeof=8, dsize=8, align=8, preferredalign=8,
+// CHECK-NEXT:  |  nvsize=8, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::B
+// CHECK-NEXT:0 |   (B vtable pointer)
+// CHECK32-NEXT:  4 |   double d2
+// CHECK64-NEXT:  8 |   double d2
+// CHECK-NEXT:   16 |   struct test2::A (virtual base)
+// CHECK-NEXT:   16 | long long l1
+// CHECK-NEXT:  | [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK32-NEXT:|  nvsize=12, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:|  nvsize=16, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::C
+// CHECK-NEXT:0 |   (C vtable pointer)
+// CHECK32-NEXT:  4 |   double d3
+// CHECK32-NEXT: 12 |   struct test2::A (virtual base)
+// CHECK32-NEXT: 12 | long long l1
+// CHECK32-NEXT:| [sizeof=20, dsize=20, align=2, preferredalign=2,
+// 

[PATCH] D79719: [AIX] Implement AIX special alignment rule about double/long double

2020-06-08 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L added inline comments.



Comment at: clang/lib/AST/RecordLayoutBuilder.cpp:666
+FirstNonOverlappingEmptyFieldHandled
+  } FirstNonOverlappingEmptyFieldStatus;
+

efriedma wrote:
> Instead of specifically tracking whether you've found an OverlappingEmpty 
> field, could you just have something like "bool FoundNonOverlappingEmptyField 
> = false;", and set it to true when you handle a field that isn't 
> OverlappingEmpty?  I don't think we need to specifically track whether we've 
> found an OverlappingEmpty field.
I think you are right. We do not need to specifically track whether we've found 
an OverlappingEmpty field. But I think we do need an enum to track if the first 
non-OverlappingEmptyField is handled or not.

Or the following case is problematic:


```
struct A {
  int : 0;
  double d;
};

```
The `double d` will mistakenly match `FieldOffset == CharUnits::Zero() && 
D->getFieldIndex() != 0 && !IsOverlappingEmptyField && 
FoundNonOverlappingEmptyField `, which we shouldn't because it is not the first 
member of the struct.





Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79719/new/

https://reviews.llvm.org/D79719



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D79719: [AIX] Implement AIX special alignment rule about double/long double

2020-06-09 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L updated this revision to Diff 269553.
Xiangling_L marked an inline comment as done.
Xiangling_L added a comment.

Replace the transient status by a local var;
Clean up the code;


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79719/new/

https://reviews.llvm.org/D79719

Files:
  clang/include/clang/AST/RecordLayout.h
  clang/include/clang/Basic/TargetInfo.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/RecordLayout.cpp
  clang/lib/AST/RecordLayoutBuilder.cpp
  clang/lib/Basic/Targets/OSTargets.h
  clang/lib/Basic/Targets/PPC.h
  clang/test/Layout/aix-double-struct-member.cpp
  clang/test/Layout/aix-no-unique-address-with-double.cpp
  clang/test/Layout/aix-virtual-function-and-base-with-double.cpp

Index: clang/test/Layout/aix-virtual-function-and-base-with-double.cpp
===
--- /dev/null
+++ clang/test/Layout/aix-virtual-function-and-base-with-double.cpp
@@ -0,0 +1,112 @@
+// RUN: %clang_cc1 -emit-llvm-only -triple powerpc-ibm-aix-xcoff \
+// RUN: -fdump-record-layouts -fsyntax-only %s 2>/dev/null | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK32 %s
+
+// RUN: %clang_cc1 -emit-llvm-only -triple powerpc64-ibm-aix-xcoff \
+// RUN: -fdump-record-layouts -fsyntax-only %s 2>/dev/null | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK64 %s
+
+namespace test1 {
+struct A {
+  double d1;
+  virtual void boo() {}
+};
+
+struct B {
+  double d2;
+  A a;
+};
+
+struct C : public A {
+  double d3;
+};
+
+int i = sizeof(B);
+int j = sizeof(C);
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::A
+// CHECK-NEXT:0 |   (A vtable pointer)
+// CHECK32-NEXT:  4 |   double d1
+// CHECK32-NEXT:| [sizeof=12, dsize=12, align=4, preferredalign=4,
+// CHECK32-NEXT:|  nvsize=12, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:  8 |   double d1
+// CHECK64-NEXT:| [sizeof=16, dsize=16, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=16, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::B
+// CHECK-NEXT:0 |   double d2
+// CHECK-NEXT:8 |   struct test1::A a
+// CHECK-NEXT:8 | (A vtable pointer)
+// CHECK32-NEXT: 12 | double d1
+// CHECK32-NEXT:| [sizeof=24, dsize=20, align=4, preferredalign=8,
+// CHECK32-NEXT:|  nvsize=20, nvalign=4, preferrednvalign=8]
+// CHECK64-NEXT: 16 | double d1
+// CHECK64-NEXT:| [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=24, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::C
+// CHECK-NEXT:0 |   struct test1::A (primary base)
+// CHECK-NEXT:0 | (A vtable pointer)
+// CHECK32-NEXT:  4 | double d1
+// CHECK32-NEXT: 12 |   double d3
+// CHECK32-NEXT:| [sizeof=20, dsize=20, align=4, preferredalign=4,
+// CHECK32-NEXT:|  nvsize=20, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:  8 | double d1
+// CHECK64-NEXT: 16 |   double d3
+// CHECK64-NEXT:| [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=24, nvalign=8, preferrednvalign=8]
+
+}; // namespace test1
+
+namespace test2 {
+struct A {
+  long long l1;
+};
+
+struct B : public virtual A {
+  double d2;
+};
+
+#pragma pack(2)
+struct C : public virtual A {
+  double __attribute__((aligned(4))) d3;
+};
+
+int i = sizeof(B);
+int j = sizeof(C);
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::A
+// CHECK-NEXT:0 |   long long l1
+// CHECK-NEXT:  | [sizeof=8, dsize=8, align=8, preferredalign=8,
+// CHECK-NEXT:  |  nvsize=8, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::B
+// CHECK-NEXT:0 |   (B vtable pointer)
+// CHECK32-NEXT:  4 |   double d2
+// CHECK64-NEXT:  8 |   double d2
+// CHECK-NEXT:   16 |   struct test2::A (virtual base)
+// CHECK-NEXT:   16 | long long l1
+// CHECK-NEXT:  | [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK32-NEXT:|  nvsize=12, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:|  nvsize=16, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::C
+// CHECK-NEXT:0 |   (C vtable pointer)
+// CHECK32-NEXT:  4 |   double d3
+// CHECK32-NEXT: 12 |   struct test2::A (virtual base)
+// CHECK32-NEXT: 12 | long long l1
+// CHECK32-NEXT:| [sizeof=20, dsize=20, align=2, preferredalign=2,
+// CHECK32-

[PATCH] D74166: [AIX][Frontend] Static init implementation for AIX considering no priority

2020-06-10 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L updated this revision to Diff 269900.
Xiangling_L marked 17 inline comments as done.
Xiangling_L added a comment.

Address the comments


Repository:
  rL LLVM

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D74166/new/

https://reviews.llvm.org/D74166

Files:
  clang/include/clang/AST/Mangle.h
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/CodeGen/CGCXXABI.h
  clang/lib/CodeGen/CGDeclCXX.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/CodeGen/CodeGenModule.h
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/CodeGen/aix-constructor-attribute.cpp
  clang/test/CodeGen/aix-destructor-attribute.cpp
  clang/test/CodeGen/aix-init-priority-attribute.cpp
  clang/test/CodeGen/static-init.cpp

Index: clang/test/CodeGen/static-init.cpp
===
--- clang/test/CodeGen/static-init.cpp
+++ clang/test/CodeGen/static-init.cpp
@@ -1,12 +1,85 @@
-// RUN: not %clang_cc1 -triple powerpc-ibm-aix-xcoff -S -emit-llvm -x c++ %s \
-// RUN: -o /dev/null 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -triple powerpc-ibm-aix-xcoff -S -emit-llvm -x c++ < %s \
+// RUN: | FileCheck %s
 
-// RUN: not %clang_cc1 -triple powerpc64-ibm-aix-xcoff -S -emit-llvm -x c++ %s \
-// RUN: -o /dev/null 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -triple powerpc64-ibm-aix-xcoff -S -emit-llvm -x c++ < %s \
+// RUN: | FileCheck %s
 
 struct test {
   test();
   ~test();
-} t;
+} t1, t2;
 
-// CHECK: error in backend: Static initialization has not been implemented on XL ABI yet.
+// CHECK: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @__sinit8000_clang_66d40ba2f9a26b497582a82a8a262181, i8* null }]
+// CHECK: @llvm.global_dtors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @__sterm8000_clang_66d40ba2f9a26b497582a82a8a262181, i8* null }]
+
+// CHECK: define internal void @__cxx_global_var_init() #0 {
+// CHECK: entry:
+// CHECK:   call void @_ZN4testC1Ev(%struct.test* @t1)
+// CHECK:   %0 = call i32 @atexit(void ()* @__dtor_t1)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__dtor_t1() #0 {
+// CHECK: entry:
+// CHECK:   call void @_ZN4testD1Ev(%struct.test* @t1)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: declare i32 @atexit(void ()*)
+
+// CHECK: define internal void @__cxx_global_var_destruct_t1() #0 {
+// CHECK: entry:
+// CHECK:   %0 = call i32 @unatexit(void ()* @__dtor_t1)
+// CHECK:   %guard.hasDtor = icmp eq i32 %0, 0
+// CHECK:   br i1 %guard.hasDtor, label %destruct.call, label %destruct.end
+
+// CHECK: destruct.call:
+// CHECK:   call void @__dtor_t1()
+// CHECK:   br label %destruct.end
+
+// CHECK: destruct.end:
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: declare i32 @unatexit(void ()*) #3
+
+// CHECK: define internal void @__cxx_global_var_init.1() #0 {
+// CHECK: entry:
+// CHECK:   call void @_ZN4testC1Ev(%struct.test* @t2)
+// CHECK:   %0 = call i32 @atexit(void ()* @__dtor_t2)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__dtor_t2() #0 {
+// CHECK: entry:
+// CHECK:   call void @_ZN4testD1Ev(%struct.test* @t2)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__cxx_global_var_destruct_t2() #0 {
+// CHECK: entry:
+// CHECK:   %0 = call i32 @unatexit(void ()* @__dtor_t2)
+// CHECK:   %guard.hasDtor = icmp eq i32 %0, 0
+// CHECK:   br i1 %guard.hasDtor, label %destruct.call, label %destruct.end
+
+// CHECK: destruct.call:
+// CHECK:   call void @__dtor_t2()
+// CHECK:   br label %destruct.end
+
+// CHECK: destruct.end:
+// CHECK:  ret void
+// CHECK: }
+
+// CHECK: define dso_local void @__sinit8000_clang_66d40ba2f9a26b497582a82a8a262181() #0 {
+// CHECK: entry:
+// CHECK:   call void @__cxx_global_var_init()
+// CHECK:   call void @__cxx_global_var_init.1()
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define dso_local void @__sterm8000_clang_66d40ba2f9a26b497582a82a8a262181() #0 {
+// CHECK: entry:
+// CHECK:   call void @__cxx_global_var_destruct_t2()
+// CHECK:   call void @__cxx_global_var_destruct_t1()
+// CHECK:   ret void
+// CHECK: }
Index: clang/test/CodeGen/aix-init-priority-attribute.cpp
===
--- /dev/null
+++ clang/test/CodeGen/aix-init-priority-attribute.cpp
@@ -0,0 +1,17 @@
+// RUN: not %clang_cc1 -triple powerpc-ibm-aix-xcoff -x c++ -emit-llvm < %s \
+// RUN: 2>&1 | FileCheck %s
+// RUN: not %clang_cc1 -triple powerpc64-ibm-aix-xcoff -x c++ -emit-llvm < %s \
+// RUN: 2>&1 | FileCheck %s
+
+class test {
+  int a;
+
+public:
+  test(int c) { a = c; }
+  ~test() { a = 0; }
+};
+
+__attribute__((init_priority(2000)))
+test t(1);
+
+// CHECK: fatal error: error in backend: 'init_priority' attribute unsupported on AIX yet
Index: clang/test/CodeGen/aix-destructor-attribute.cpp
===
--- /dev/null
+

[PATCH] D74166: [AIX][Frontend] Static init implementation for AIX considering no priority

2020-06-10 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L added inline comments.



Comment at: clang/lib/AST/ItaniumMangle.cpp:5217
+  else
+Mangler.getStream() << D->getName();
+}

jasonliu wrote:
> If I understand correctly, this function will come in pair with 
> `__cxx_global_var_init`.
> `__cxx_global_var_init` use number as suffix in the end to avoid duplication 
> when there is more than one of those, but we are using the variable name as 
> suffix here instead.
> Do we want to use number as suffix here to match what `__cxx_global_var_init` 
> does? It would help people to recognize the pairs and make them more 
> symmetric. 
This is somewhere I am kinda on the fence. Personally, I think embed decl name 
in the __cxx_global_var_destruct_ / __cxx_global_vat_init_ as 
`mangleDynamicAtExitDestructor` does is more helpful for the user to debug the 
static init.
I am not sure if we want to give up that benefit and be consistent with current 
`__cxx_global_vat_init_ ` using number suffix or do we want to replace number 
suffix by decl name for `__cxx_global_vat_init_ ` as well.



Comment at: clang/lib/CodeGen/CGCXXABI.h:113
+
+  virtual bool isCXXGlobalInitAndDtorFuncInternal() const { return true; }
+

jasonliu wrote:
> Do we need this isCXXGlobalInitAndDtorFuncInternal? Looks like it's always 
> going to return ! useSinitAndSterm() result.
AFAIK, not all platforms which use sinit and sterm have external linkage 
sinit/sterm functions. And also since for 7.2 AIX we are considering change 
sinit/sterm to internal linkage symbols, I seperate this query out.



Comment at: clang/lib/CodeGen/CGDeclCXX.cpp:305
+  if (llvm::Function *unatexitFn =
+  dyn_cast(unatexit.getCallee()))
+unatexitFn->setDoesNotThrow();

jasonliu wrote:
> Is there a valid case that unatexit.getCallee() returns a type which could 
> not be cast to llvm::Function?
> i.e. Could we use cast instead of dyn_cast?
I used `cast` instead of `dyn_cast` before Diff 9 actually, and then I noticed 
that `clang-tidy` gave error and asked me to use `dyn_cast` instead. Cannot 
recall what the error says though...



Comment at: clang/lib/CodeGen/CodeGenModule.h:20
 #include "SanitizerMetadata.h"
+#include "clang/AST/Attr.h"
 #include "clang/AST/DeclCXX.h"

jasonliu wrote:
> Is this Attr.h needed somewhere in this file?
Oops..this is something I forgot to remove. Good catch!



Comment at: clang/lib/CodeGen/ItaniumCXXABI.cpp:4481
+
+  llvm::BasicBlock *DestructCheckBlock = 
CGF.createBasicBlock("destruct.check");
+  llvm::BasicBlock *EndBlock = CGF.createBasicBlock("destruct.end");

jasonliu wrote:
> I think we need a better naming for this and make it consistent with the end 
> block below.
> As it is for now, `destruct.check` is confusing, as we are not checking 
> anything here and we are just going to call destructor directly in this 
> block. 
Thanks, I will try `destruct.call` instead.


Repository:
  rL LLVM

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D74166/new/

https://reviews.llvm.org/D74166



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D74166: [AIX][Frontend] Static init implementation for AIX considering no priority

2020-06-11 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L updated this revision to Diff 270267.
Xiangling_L marked 21 inline comments as done.
Xiangling_L added a comment.

Address another round of reviews;


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D74166/new/

https://reviews.llvm.org/D74166

Files:
  clang/include/clang/AST/Mangle.h
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/CodeGen/CGCXXABI.h
  clang/lib/CodeGen/CGDeclCXX.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/CodeGen/CodeGenModule.h
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/CodeGen/aix-constructor-attribute.cpp
  clang/test/CodeGen/aix-destructor-attribute.cpp
  clang/test/CodeGen/aix-init-priority-attribute.cpp
  clang/test/CodeGen/static-init.cpp

Index: clang/test/CodeGen/static-init.cpp
===
--- clang/test/CodeGen/static-init.cpp
+++ clang/test/CodeGen/static-init.cpp
@@ -1,12 +1,87 @@
-// RUN: not %clang_cc1 -triple powerpc-ibm-aix-xcoff -S -emit-llvm -x c++ %s \
-// RUN: -o /dev/null 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -triple powerpc-ibm-aix-xcoff -S -emit-llvm -x c++ \
+// RUN: -fno-use-cxa-atexit < %s | \
+// RUN:   FileCheck %s
 
-// RUN: not %clang_cc1 -triple powerpc64-ibm-aix-xcoff -S -emit-llvm -x c++ %s \
-// RUN: -o /dev/null 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -triple powerpc64-ibm-aix-xcoff -S -emit-llvm -x c++ \
+// RUN: -fno-use-cxa-atexit < %s | \
+// RUN:   FileCheck %s
 
 struct test {
   test();
   ~test();
-} t;
+} t1, t2;
 
-// CHECK: error in backend: Static initialization has not been implemented on XL ABI yet.
+// CHECK: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @__sinit8000_clang_66d40ba2f9a26b497582a82a8a262181, i8* null }]
+// CHECK: @llvm.global_dtors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @__sterm8000_clang_66d40ba2f9a26b497582a82a8a262181, i8* null }]
+
+// CHECK: define internal void @__cxx_global_var_init() #0 {
+// CHECK: entry:
+// CHECK:   call void @_ZN4testC1Ev(%struct.test* @t1)
+// CHECK:   %0 = call i32 @atexit(void ()* @__dtor_t1)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__dtor_t1() #0 {
+// CHECK: entry:
+// CHECK:   call void @_ZN4testD1Ev(%struct.test* @t1)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: declare i32 @atexit(void ()*)
+
+// CHECK: define internal void @__cxx_global_var_destruct_t1() #0 {
+// CHECK: entry:
+// CHECK:   %0 = call i32 @unatexit(void ()* @__dtor_t1)
+// CHECK:   %guard.needsDestruct = icmp eq i32 %0, 0
+// CHECK:   br i1 %guard.needsDestruct, label %destruct.call, label %destruct.end
+
+// CHECK: destruct.call:
+// CHECK:   call void @__dtor_t1()
+// CHECK:   br label %destruct.end
+
+// CHECK: destruct.end:
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: declare i32 @unatexit(void ()*) #3
+
+// CHECK: define internal void @__cxx_global_var_init.1() #0 {
+// CHECK: entry:
+// CHECK:   call void @_ZN4testC1Ev(%struct.test* @t2)
+// CHECK:   %0 = call i32 @atexit(void ()* @__dtor_t2)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__dtor_t2() #0 {
+// CHECK: entry:
+// CHECK:   call void @_ZN4testD1Ev(%struct.test* @t2)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__cxx_global_var_destruct_t2() #0 {
+// CHECK: entry:
+// CHECK:   %0 = call i32 @unatexit(void ()* @__dtor_t2)
+// CHECK:   %guard.needsDestruct = icmp eq i32 %0, 0
+// CHECK:   br i1 %guard.needsDestruct, label %destruct.call, label %destruct.end
+
+// CHECK: destruct.call:
+// CHECK:   call void @__dtor_t2()
+// CHECK:   br label %destruct.end
+
+// CHECK: destruct.end:
+// CHECK:  ret void
+// CHECK: }
+
+// CHECK: define dso_local void @__sinit8000_clang_66d40ba2f9a26b497582a82a8a262181() #0 {
+// CHECK: entry:
+// CHECK:   call void @__cxx_global_var_init()
+// CHECK:   call void @__cxx_global_var_init.1()
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define dso_local void @__sterm8000_clang_66d40ba2f9a26b497582a82a8a262181() #0 {
+// CHECK: entry:
+// CHECK:   call void @__cxx_global_var_destruct_t2()
+// CHECK:   call void @__cxx_global_var_destruct_t1()
+// CHECK:   ret void
+// CHECK: }
Index: clang/test/CodeGen/aix-init-priority-attribute.cpp
===
--- /dev/null
+++ clang/test/CodeGen/aix-init-priority-attribute.cpp
@@ -0,0 +1,17 @@
+// RUN: not %clang_cc1 -triple powerpc-ibm-aix-xcoff -x c++ -emit-llvm < %s \
+// RUN: 2>&1 | FileCheck %s
+// RUN: not %clang_cc1 -triple powerpc64-ibm-aix-xcoff -x c++ -emit-llvm < %s \
+// RUN: 2>&1 | FileCheck %s
+
+class test {
+  int a;
+
+public:
+  test(int c) { a = c; }
+  ~test() { a = 0; }
+};
+
+__attribute__((init_priority(2000)))
+test t(1);
+
+// CHECK: fatal error: error in backend: 'init_priority' attribute unsupported on AIX yet
Index: clang/test/CodeGen/aix-destructor-attribute

[PATCH] D74166: [AIX][Frontend] Static init implementation for AIX considering no priority

2020-06-11 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L added inline comments.



Comment at: clang/include/clang/AST/Mangle.h:178
 
+  virtual void mangleDynamicDestructor(const VarDecl *D, raw_ostream &Out) = 0;
+

hubert.reinterpretcast wrote:
> I am not sure "destructor" is the right term here. This seems to be an 
> analogue to the functions named using `mangleDynamicAtExitDestructor`, except 
> that those rather directly perform destruction and are registered with 
> `atexit` during initialization whereas these perform finalization and are 
> "registered" by being called from an "sterm" function. What are the thoughts 
> on `mangleDynamicStermFinalizer`?
`mangleDynamicDestructor` is an analogue to `mangleDynamicInitializer` actually.

From this perspective, I think `mangleDynamicStermFinalizer` is good.



Comment at: clang/lib/CodeGen/CodeGenModule.h:1058
+  void AddCXXDtorEntry(llvm::FunctionCallee DtorFn) {
+CXXGlobalDtors.emplace_back(DtorFn.getFunctionType(), DtorFn.getCallee(),
+nullptr);

hubert.reinterpretcast wrote:
> The description of `CXXGlobalDtors` is
> > Global destructor functions and arguments that need to run on termination.
> 
Currently, only Apple Kernal extension will use `AddCXXDtorEntry` to add 
variable destructor to CXXGlobalDtors.
An example is:

```
$cat test.cpp
class test {
   int a;
public:
test(int c) {a = c;}
~test() {a = 0;}
} t(1);


$clang --driver-mode=g++ -target x86_64-apple-darwin10 -fapple-kext -flto -S -o 
- test.cpp

...
define internal void @_GLOBAL__D_a() #0 {
entry:
  call void @_ZN4testD1Ev(%class.test* @t)   #~test() {a = 0;}
  ret void
}
```

Since the usage as you said below does not match with our sterm finalizer 
function `__cxx_global_var_destruct`, I am thinking we can either modify the 
name and the description of `CXXGlobalDtors` to make it also fit AIX or we can 
define a brand new `CXXStermFinalizers` vector and also related facility to 
`GenerateCXXStermFinalizerFunc` instead. 

An example of modification I have in mind is:
`CXXGlobalDtorsOrStermFinalizers`


> Global destructor functions and arguments that need to run on termination;
> When UseSinitAndSterm is set, it contains sterm finalizer functions instead 
> that need to run on unloading a shared library.



I would prefer the modification way to save a lot effort. Any thoughts on it?



Comment at: clang/lib/CodeGen/ItaniumCXXABI.cpp:4447
+
+  // Create __dtor function for the var decl.
+  llvm::Function *dtorStub = CGF.createAtExitStub(D, dtor, addr);

hubert.reinterpretcast wrote:
> We should probably report_fatal_error if `CXAAtExit` (the option) is true 
> before this line. This would imply driver changes to default AIX to using 
> `-fno-use-cxa-atexit`. An associated test file is 
> https://github.com/llvm/llvm-project/blame/master/clang/test/Driver/cxa-atexit.cpp.
Maybe we should add `-fno-use-cxa-atexit` to driver in a follow-up patch?



Comment at: clang/test/CodeGen/static-init.cpp:15
+
+// CHECK: define internal void @__cxx_global_var_init() #0 {
+// CHECK: entry:

jasonliu wrote:
> #0 could be removed.
Why I chose to keep this `#0` is because to remove it, we would either remove 
the following `{` which I kinda feel makes the function look not nice or we 
need to match `#0` with regex which I think is redundant. 


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D74166/new/

https://reviews.llvm.org/D74166



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D74166: [AIX][Frontend] Static init implementation for AIX considering no priority

2020-06-12 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L updated this revision to Diff 270548.
Xiangling_L marked 35 inline comments as done.
Xiangling_L edited the summary of this revision.
Xiangling_L added a comment.

Address another round of reviews;


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D74166/new/

https://reviews.llvm.org/D74166

Files:
  clang/include/clang/AST/Mangle.h
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/CodeGen/CGCXXABI.h
  clang/lib/CodeGen/CGDeclCXX.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/CodeGen/CodeGenModule.h
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/CodeGen/aix-constructor-attribute.cpp
  clang/test/CodeGen/aix-destructor-attribute.cpp
  clang/test/CodeGen/aix-init-priority-attribute.cpp
  clang/test/CodeGen/static-init.cpp

Index: clang/test/CodeGen/static-init.cpp
===
--- clang/test/CodeGen/static-init.cpp
+++ clang/test/CodeGen/static-init.cpp
@@ -1,12 +1,139 @@
-// RUN: not %clang_cc1 -triple powerpc-ibm-aix-xcoff -S -emit-llvm -x c++ %s \
-// RUN: -o /dev/null 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -triple powerpc-ibm-aix-xcoff -S -emit-llvm -x c++ \
+// RUN: -fno-use-cxa-atexit -std=c++2a < %s | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK32 %s
 
-// RUN: not %clang_cc1 -triple powerpc64-ibm-aix-xcoff -S -emit-llvm -x c++ %s \
-// RUN: -o /dev/null 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -triple powerpc64-ibm-aix-xcoff -S -emit-llvm -x c++ \
+// RUN: -fno-use-cxa-atexit -std=c++2a < %s | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK64 %s
 
-struct test {
-  test();
-  ~test();
-} t;
+namespace test1 {
+  struct Test1 {
+Test1();
+~Test1();
+  } t1, t2;
+}; // namespace test1
 
-// CHECK: error in backend: Static initialization has not been implemented on XL ABI yet.
+namespace test2 {
+  int foo() { return 3; }
+  int x = foo();
+}; // namespace test2
+
+namespace test3 {
+  struct Test {
+constexpr Test() {};
+~Test() {};
+  };
+
+  constinit Test t;
+}; // namespace test3
+
+// CHECK: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @__sinit8000_clang_510e898aa8d263cac999dd03eeed5b51, i8* null }]
+// CHECK: @llvm.global_dtors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @__sterm8000_clang_510e898aa8d263cac999dd03eeed5b51, i8* null }]
+
+// CHECK: define internal void @__cxx_global_var_init() #0 {
+// CHECK: entry: 
+// CHECK:   call void @_ZN5test15Test1C1Ev(%"struct.test1::Test1"* @_ZN5test12t1E)
+// CHECK:   %0 = call i32 @atexit(void ()* @__dtor__ZN5test12t1E)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__dtor__ZN5test12t1E() #0 {
+// CHECK: entry:
+// CHECK:   call void @_ZN5test15Test1D1Ev(%"struct.test1::Test1"* @_ZN5test12t1E)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: declare i32 @atexit(void ()*)
+
+// CHECK: define internal void @__finalize__ZN5test12t1E() #0 {
+// CHECK: entry:
+// CHECK:   %0 = call i32 @unatexit(void ()* @__dtor__ZN5test12t1E)
+// CHECK:   %needsDestruct = icmp eq i32 %0, 0
+// CHECK:   br i1 %needsDestruct, label %destruct.call, label %destruct.end
+
+// CHECK: destruct.call:
+// CHECK:   call void @__dtor__ZN5test12t1E()
+// CHECK:   br label %destruct.end
+
+// CHECK: destruct.end:
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: declare i32 @unatexit(void ()*)
+
+// CHECK: define internal void @__cxx_global_var_init.1() #0 {
+// CHECK: entry:
+// CHECK:   call void @_ZN5test15Test1C1Ev(%"struct.test1::Test1"* @_ZN5test12t2E)
+// CHECK:   %0 = call i32 @atexit(void ()* @__dtor__ZN5test12t2E)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__dtor__ZN5test12t2E() #0 {
+// CHECK: entry:
+// CHECK:   call void @_ZN5test15Test1D1Ev(%"struct.test1::Test1"* @_ZN5test12t2E)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__finalize__ZN5test12t2E() #0 {
+// CHECK: entry:
+// CHECK:   %0 = call i32 @unatexit(void ()* @__dtor__ZN5test12t2E)
+// CHECK:   %needsDestruct = icmp eq i32 %0, 0
+// CHECK:   br i1 %needsDestruct, label %destruct.call, label %destruct.end
+
+// CHECK: destruct.call:
+// CHECK:   call void @__dtor__ZN5test12t2E()
+// CHECK:   br label %destruct.end
+
+// CHECK: destruct.end:
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__cxx_global_var_init.2() #0 {
+// CHECK: entry:
+// CHECK32: %call = call i32 @_ZN5test23fooEv()
+// CHECK64: %call = call signext i32 @_ZN5test23fooEv()
+// CHECK:   store i32 %call, i32* @_ZN5test21xE
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__cxx_global_var_init.3() #0 {
+// CHECK: entry:
+// CHECK:   %0 = call i32 @atexit(void ()* @__dtor__ZN5test31tE)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__dtor__ZN5test31tE() #0 {
+// CHECK: e

[PATCH] D74166: [AIX][Frontend] Static init implementation for AIX considering no priority

2020-06-12 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L added inline comments.



Comment at: clang/lib/CodeGen/CGDeclCXX.cpp:639
+  if (CXXGlobalInits.empty())
+return;
 

hubert.reinterpretcast wrote:
> Can this part be committed in a separate patch? It does not appear to have 
> dependencies on other parts of this patch and has the appearance of being a 
> possible change for other platforms.
Sure. I will create a NFC patch for this part and try to commit it first. But 
so far, I think I can keep this part in this patch just for review purpose to 
make the patch look nicer?



Comment at: clang/lib/CodeGen/CGDeclCXX.cpp:704
   AddGlobalDtor(Fn);
+  CXXGlobalDtors.clear();
 }

hubert.reinterpretcast wrote:
> If this is another drive-by fix, can we put it in a separate patch?
Sure, I will put it in the above mentioned clean-up NFC patch as well.



Comment at: clang/lib/CodeGen/CGDeclCXX.cpp:700
+
+Fn = CreateGlobalInitOrDestructFunction(
+FTy, llvm::Twine("__sterm8000_clang_") + GlobalUniqueModuleId, FI,

hubert.reinterpretcast wrote:
> The called function is to be renamed.
Any suggestions here about how to represent the functionality of `__sterm` and 
`_GLOBAL__D_a` into one word? Cannot think of a good name...

Actually I am wondering do we need to rename the `Destruct` part? The `__sterm` 
and `_GLOBAL__D_a` do destruct the object by calling sterm finalizers and 
object destructors?



Comment at: clang/lib/CodeGen/CGDeclCXX.cpp:807
 
 void CodeGenFunction::GenerateCXXGlobalDtorsFunc(
 llvm::Function *Fn,

hubert.reinterpretcast wrote:
> This function is to be renamed.
 I will try `GenerateCXXGlobalDestructFunc` based on the thoughts as I also 
mentioned elsewhere that the `__sterm` and `_GLOBAL__D_` function do destruct 
the object by calling sterm finalizers and object destructors.

Any suggestions or concerns about this renaming? Or do we really need to rename 
this one?



Comment at: clang/lib/CodeGen/ItaniumCXXABI.cpp:4467
+
+  // Create a variable destruction function.
+  const CGFunctionInfo &FI = CGM.getTypes().arrangeNullaryFunction();

hubert.reinterpretcast wrote:
> Suggestion:
> Create the finalization action associated with a variable.
I don't get your point, can you elaborate on this a little bit?



Comment at: clang/test/CodeGen/static-init.cpp:8
+// RUN:   FileCheck %s
 
 struct test {

jasonliu wrote:
> Looks like the non-inline comments are easier to get ignored and missed, so I 
> will copy paste the non-inlined comment I previously had:
> ```
> -fregister_global_dtors_with_atexit does not seem to work properly in current 
> implementation.
> We should consider somehow disabling/report_fatal_error it instead of letting 
> it generate invalid code on AIX.
> ```
Thanks for doing so!

The semantic of `global_dtors` here on AIX is `__sterm` function, which we are 
never gonna register with `__atexit`. I am thinking we can disable it in a 
follow-up driver patch with the handling of `-fno-use-cxa-atexit`.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D74166/new/

https://reviews.llvm.org/D74166



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D74166: [AIX][Frontend] Static init implementation for AIX considering no priority

2020-06-16 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L updated this revision to Diff 271156.
Xiangling_L marked 35 inline comments as done.
Xiangling_L added a comment.

Renamed some functions;
Add one more test;
etc.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D74166/new/

https://reviews.llvm.org/D74166

Files:
  clang/include/clang/AST/Mangle.h
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/CodeGen/CGCXXABI.h
  clang/lib/CodeGen/CGDeclCXX.cpp
  clang/lib/CodeGen/CGOpenMPRuntime.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/CodeGen/CodeGenModule.h
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/lib/CodeGen/MicrosoftCXXABI.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/CodeGen/aix-constructor-attribute.cpp
  clang/test/CodeGen/aix-destructor-attribute.cpp
  clang/test/CodeGen/aix-init-priority-attribute.cpp
  clang/test/CodeGen/static-init.cpp

Index: clang/test/CodeGen/static-init.cpp
===
--- clang/test/CodeGen/static-init.cpp
+++ clang/test/CodeGen/static-init.cpp
@@ -1,12 +1,175 @@
-// RUN: not %clang_cc1 -triple powerpc-ibm-aix-xcoff -S -emit-llvm -x c++ %s \
-// RUN: -o /dev/null 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -triple powerpc-ibm-aix-xcoff -S -emit-llvm -x c++ \
+// RUN: -fno-use-cxa-atexit -std=c++2a < %s | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK32 %s
 
-// RUN: not %clang_cc1 -triple powerpc64-ibm-aix-xcoff -S -emit-llvm -x c++ %s \
-// RUN: -o /dev/null 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -triple powerpc64-ibm-aix-xcoff -S -emit-llvm -x c++ \
+// RUN: -fno-use-cxa-atexit -std=c++2a < %s | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK64 %s
 
-struct test {
-  test();
-  ~test();
-} t;
+namespace test1 {
+  struct Test1 {
+Test1();
+~Test1();
+  } t1, t2;
+} // namespace test1
 
-// CHECK: error in backend: Static initialization has not been implemented on XL ABI yet.
+namespace test2 {
+  int foo() { return 3; }
+  int x = foo();
+} // namespace test2
+
+namespace test3 {
+  struct Test3 {
+constexpr Test3() {};
+~Test3() {};
+  };
+
+  constinit Test3 t;
+} // namespace test3
+
+namespace test4 {
+  struct Test4 { 
+Test4();
+~Test4();
+  };
+
+  void f() {
+static Test4 staticLocal;
+  }
+} // namespace test4
+
+// CHECK: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @__sinit8000_clang_1145401da454a7baad10bfe313c46638, i8* null }]
+// CHECK: @llvm.global_dtors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @__sterm8000_clang_1145401da454a7baad10bfe313c46638, i8* null }]
+
+// CHECK: define internal void @__cxx_global_var_init() #0 {
+// CHECK: entry:
+// CHECK:   call void @_ZN5test15Test1C1Ev(%"struct.test1::Test1"* @_ZN5test12t1E)
+// CHECK:   %0 = call i32 @atexit(void ()* @__dtor__ZN5test12t1E) #3
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__dtor__ZN5test12t1E() #0 {
+// CHECK: entry:
+// CHECK:   call void @_ZN5test15Test1D1Ev(%"struct.test1::Test1"* @_ZN5test12t1E)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: declare i32 @atexit(void ()*)
+
+// CHECK: define internal void @__finalize__ZN5test12t1E() #0 {
+// CHECK: entry:
+// CHECK:   %0 = call i32 @unatexit(void ()* @__dtor__ZN5test12t1E) #3
+// CHECK:   %needs_destruct = icmp eq i32 %0, 0
+// CHECK:   br i1 %needs_destruct, label %destruct.call, label %destruct.end
+
+// CHECK: destruct.call:
+// CHECK:   call void @__dtor__ZN5test12t1E()
+// CHECK:   br label %destruct.end
+
+// CHECK: destruct.end:
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: declare i32 @unatexit(void ()*)
+
+// CHECK: define internal void @__cxx_global_var_init.1() #0 {
+// CHECK: entry:
+// CHECK:   call void @_ZN5test15Test1C1Ev(%"struct.test1::Test1"* @_ZN5test12t2E)
+// CHECK:   %0 = call i32 @atexit(void ()* @__dtor__ZN5test12t2E)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__dtor__ZN5test12t2E() #0 {
+// CHECK: entry:
+// CHECK:   call void @_ZN5test15Test1D1Ev(%"struct.test1::Test1"* @_ZN5test12t2E)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__finalize__ZN5test12t2E() #0 {
+// CHECK: entry:
+// CHECK:   %0 = call i32 @unatexit(void ()* @__dtor__ZN5test12t2E)
+// CHECK:   %needs_destruct = icmp eq i32 %0, 0
+// CHECK:   br i1 %needs_destruct, label %destruct.call, label %destruct.end
+
+// CHECK: destruct.call:
+// CHECK:   call void @__dtor__ZN5test12t2E()
+// CHECK:   br label %destruct.end
+
+// CHECK: destruct.end:
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__cxx_global_var_init.2() #0 {
+// CHECK: entry:
+// CHECK32: %call = call i32 @_ZN5test23fooEv()
+// CHECK64: %call = call signext i32 @_ZN5test23fooEv()
+// CHECK:   store i32 %call, i32* @_ZN5test21xE
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__cxx_global_var_ini

[PATCH] D74166: [AIX][Frontend] Static init implementation for AIX considering no priority

2020-06-16 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L added inline comments.



Comment at: clang/lib/CodeGen/ItaniumCXXABI.cpp:4489
+  // DestructCallBlock, otherwise jump to EndBlock directly.
+  CGF.EmitCXXGuardedInitBranch(NeedsDestruct, DestructCallBlock, EndBlock,
+   CodeGenFunction::GuardKind::VariableGuard, &D);

hubert.reinterpretcast wrote:
> Please add a test for a static local. Note the `branch_weights`. I do not 
> believe the `branch_weights` associated with guarded initialization for a 
> static local (what the called function is meant to deal with) is necessarily 
> appropriate for a branch associated with finalization-on-unload.
Thank you for pointing this out. I will adjust the function name to 
`EmitCXXGuardedInitOrDestructBranch` later to match our usage.

In terms of `branch_weights`,  this is something I am not familiar with. So 
please correct me if I am wrong. Some of my superficial thoughts would be are 
we able to apply `branch_weights` on a branch associated with 
finalization-on-unload? Should it be set as `nullptr`,  because we would not 
know how many times we will call `__sterm`(and each sterm finalizer contained)?

BTW, I will add a testcase for a static local and we can update the 
`branch_weights` part later along with the reviews.



Comment at: clang/test/CodeGen/static-init.cpp:8
+// RUN:   FileCheck %s
 
 struct test {

hubert.reinterpretcast wrote:
> Xiangling_L wrote:
> > jasonliu wrote:
> > > Looks like the non-inline comments are easier to get ignored and missed, 
> > > so I will copy paste the non-inlined comment I previously had:
> > > ```
> > > -fregister_global_dtors_with_atexit does not seem to work properly in 
> > > current implementation.
> > > We should consider somehow disabling/report_fatal_error it instead of 
> > > letting it generate invalid code on AIX.
> > > ```
> > Thanks for doing so!
> > 
> > The semantic of `global_dtors` here on AIX is `__sterm` function, which we 
> > are never gonna register with `__atexit`. I am thinking we can disable it 
> > in a follow-up driver patch with the handling of `-fno-use-cxa-atexit`.
> The semantic of `global_dtors` is not limited to the `__sterm` functions 
> associated with C++ cleanup actions. With respect to user-declared 
> `__attribute__((__destructor__))` functions, the option could improve the 
> interleaving of those cleanup actions with cleanup actions registered by 
> user-declared `__attribute__((__constructor__))` functions.
> 
> This provides that rationale for separating the `__sterm` functions 
> associated with the C++ cleanup actions from the other "destructor" functions.
Yeah, I agree that the semantic of `global_dtors` should contain both `__sterm` 
and `__attribute__((__destructor__))` dtors. And we do need some rationale to 
separate `__sterm` and those other `destructor` functions out for AIX.

However, I doubt the `-fregister_global_dtors_with_atexit` option is something 
we should use. Cuz dtors with `__attribute__((__destructor__))` actually are 
equivalent to `__dtor` functions in AIX's semantic which need to be registered 
with `__atexit`. However, we shouldn't register `__sterm` with `__atexit`. So 
it seems this option does not work well for AIX either we set it to true or 
false, and we need to figure something else out when we start supporting 
`__attribute__((__destructor__))` and `__attribute__((__constructor__))`?



Comment at: clang/test/CodeGen/static-init.cpp:31
+// CHECK: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] 
[{ i32, void ()*, i8* } { i32 65535, void ()* 
@__sinit8000_clang_510e898aa8d263cac999dd03eeed5b51, i8* null }]
+// CHECK: @llvm.global_dtors = appending global [1 x { i32, void ()*, i8* }] 
[{ i32, void ()*, i8* } { i32 65535, void ()* 
@__sterm8000_clang_510e898aa8d263cac999dd03eeed5b51, i8* null }]
+

hubert.reinterpretcast wrote:
> hubert.reinterpretcast wrote:
> > Okay, the restricted scope of this patch seems to landed in a place where 
> > how the `llvm.global_dtors` array will be handled is not indicated...
> > 
> > The backend should implement the semantics of the IR construct. When 
> > handling said array in the IR, it seems the method to handle the requisite 
> > semantics would be to generate an alias (with the appropriate linkage for 
> > the linker to pick it up) that is named using the `__sinit`/`__sterm` 
> > convention. Which is to say that at least some part of the naming should 
> > eventually move into the LLVM side and out of Clang.
> > 
> > Please update the description of this patch to indicate that:
> > 
> >   - The `llvm.global_ctors` and `llvm.global_dtors` functionality has not 
> > yet been implemented on AIX.
> >   - This patch temporarily side-steps the need to implement that 
> > functionality.
> >   - The apparent uses of that functionality in this patch (with respect to 
> > the name of the functions involved) are 

[PATCH] D81972: [NFC] Cleanup of EmitCXXGlobalInitFunc() and EmitCXXGlobalDtorFunc()

2020-06-16 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L created this revision.
Xiangling_L added reviewers: jasonliu, hubert.reinterpretcast.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
Xiangling_L edited the summary of this revision.

Tidy up some code of `EmitCXXGlobalInitFunc()` and `EmitCXXGlobalDtorFunc()`as 
the pre-work of [AIX][Frontend] Static init implementation for AIX considering 
no priority [https://reviews.llvm.org/D74166] patch.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D81972

Files:
  clang/lib/CodeGen/CGDeclCXX.cpp


Index: clang/lib/CodeGen/CGDeclCXX.cpp
===
--- clang/lib/CodeGen/CGDeclCXX.cpp
+++ clang/lib/CodeGen/CGDeclCXX.cpp
@@ -533,6 +533,23 @@
   CXXThreadLocals.clear();
 }
 
+static StringRef getTransformedFileName(llvm::Module &M,
+SmallString<128> &FileName) {
+  FileName = llvm::sys::path::filename(M.getName());
+
+  if (FileName.empty())
+FileName = "";
+
+  for (size_t i = 0; i < FileName.size(); ++i) {
+// Replace everything that's not [a-zA-Z0-9._] with a _. This set happens
+// to be the set of C preprocessing numbers.
+if (!isPreprocessingNumberBody(FileName[i]))
+  FileName[i] = '_';
+  }
+
+  return FileName;
+}
+
 void
 CodeGenModule::EmitCXXGlobalInitFunc() {
   while (!CXXGlobalInits.empty() && !CXXGlobalInits.back())
@@ -577,22 +594,15 @@
 PrioritizedCXXGlobalInits.clear();
   }
 
-  // Include the filename in the symbol name. Including "sub_" matches gcc and
-  // makes sure these symbols appear lexicographically behind the symbols with
-  // priority emitted above.
-  SmallString<128> FileName = llvm::sys::path::filename(getModule().getName());
-  if (FileName.empty())
-FileName = "";
-
-  for (size_t i = 0; i < FileName.size(); ++i) {
-// Replace everything that's not [a-zA-Z0-9._] with a _. This set happens
-// to be the set of C preprocessing numbers.
-if (!isPreprocessingNumberBody(FileName[i]))
-  FileName[i] = '_';
-  }
-
+  // Include the filename in the symbol name. Including "sub_" matches gcc
+  // and makes sure these symbols appear lexicographically behind the symbols
+  // with priority emitted above.
+  SmallString<128> FileName;
   llvm::Function *Fn = CreateGlobalInitOrDestructFunction(
-  FTy, llvm::Twine("_GLOBAL__sub_I_", FileName), FI);
+  FTy,
+  llvm::Twine("_GLOBAL__sub_I_",
+  getTransformedFileName(getModule(), FileName)),
+  FI);
 
   CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, CXXGlobalInits);
   AddGlobalCtor(Fn);
@@ -631,6 +641,7 @@
 
   CodeGenFunction(*this).GenerateCXXGlobalDtorsFunc(Fn, CXXGlobalDtors);
   AddGlobalDtor(Fn);
+  CXXGlobalDtors.clear();
 }
 
 /// Emit the code necessary to initialize the given global variable.


Index: clang/lib/CodeGen/CGDeclCXX.cpp
===
--- clang/lib/CodeGen/CGDeclCXX.cpp
+++ clang/lib/CodeGen/CGDeclCXX.cpp
@@ -533,6 +533,23 @@
   CXXThreadLocals.clear();
 }
 
+static StringRef getTransformedFileName(llvm::Module &M,
+SmallString<128> &FileName) {
+  FileName = llvm::sys::path::filename(M.getName());
+
+  if (FileName.empty())
+FileName = "";
+
+  for (size_t i = 0; i < FileName.size(); ++i) {
+// Replace everything that's not [a-zA-Z0-9._] with a _. This set happens
+// to be the set of C preprocessing numbers.
+if (!isPreprocessingNumberBody(FileName[i]))
+  FileName[i] = '_';
+  }
+
+  return FileName;
+}
+
 void
 CodeGenModule::EmitCXXGlobalInitFunc() {
   while (!CXXGlobalInits.empty() && !CXXGlobalInits.back())
@@ -577,22 +594,15 @@
 PrioritizedCXXGlobalInits.clear();
   }
 
-  // Include the filename in the symbol name. Including "sub_" matches gcc and
-  // makes sure these symbols appear lexicographically behind the symbols with
-  // priority emitted above.
-  SmallString<128> FileName = llvm::sys::path::filename(getModule().getName());
-  if (FileName.empty())
-FileName = "";
-
-  for (size_t i = 0; i < FileName.size(); ++i) {
-// Replace everything that's not [a-zA-Z0-9._] with a _. This set happens
-// to be the set of C preprocessing numbers.
-if (!isPreprocessingNumberBody(FileName[i]))
-  FileName[i] = '_';
-  }
-
+  // Include the filename in the symbol name. Including "sub_" matches gcc
+  // and makes sure these symbols appear lexicographically behind the symbols
+  // with priority emitted above.
+  SmallString<128> FileName;
   llvm::Function *Fn = CreateGlobalInitOrDestructFunction(
-  FTy, llvm::Twine("_GLOBAL__sub_I_", FileName), FI);
+  FTy,
+  llvm::Twine("_GLOBAL__sub_I_",
+  getTransformedFileName(getModule(), FileName)),
+  FI);
 
   CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, CXXGlobalInits);
   AddGlobalCtor(Fn);
@@ -631,6 +641,7 @@
 
   CodeGenFunction(*this).GenerateCXXGlobalDtorsFunc(Fn,

[PATCH] D81972: [NFC] Cleanup of EmitCXXGlobalInitFunc() and EmitCXXGlobalDtorFunc()

2020-06-17 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L updated this revision to Diff 271389.
Xiangling_L marked an inline comment as done.
Xiangling_L added a comment.

Minor change;


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D81972/new/

https://reviews.llvm.org/D81972

Files:
  clang/lib/CodeGen/CGDeclCXX.cpp


Index: clang/lib/CodeGen/CGDeclCXX.cpp
===
--- clang/lib/CodeGen/CGDeclCXX.cpp
+++ clang/lib/CodeGen/CGDeclCXX.cpp
@@ -533,6 +533,23 @@
   CXXThreadLocals.clear();
 }
 
+static StringRef getTransformedFileName(llvm::Module &M,
+SmallString<128> &FileName) {
+  FileName = llvm::sys::path::filename(M.getName());
+
+  if (FileName.empty())
+FileName = "";
+
+  for (size_t i = 0; i < FileName.size(); ++i) {
+// Replace everything that's not [a-zA-Z0-9._] with a _. This set happens
+// to be the set of C preprocessing numbers.
+if (!isPreprocessingNumberBody(FileName[i]))
+  FileName[i] = '_';
+  }
+
+  return FileName;
+}
+
 void
 CodeGenModule::EmitCXXGlobalInitFunc() {
   while (!CXXGlobalInits.empty() && !CXXGlobalInits.back())
@@ -577,22 +594,18 @@
 PrioritizedCXXGlobalInits.clear();
   }
 
-  // Include the filename in the symbol name. Including "sub_" matches gcc and
-  // makes sure these symbols appear lexicographically behind the symbols with
-  // priority emitted above.
-  SmallString<128> FileName = llvm::sys::path::filename(getModule().getName());
-  if (FileName.empty())
-FileName = "";
-
-  for (size_t i = 0; i < FileName.size(); ++i) {
-// Replace everything that's not [a-zA-Z0-9._] with a _. This set happens
-// to be the set of C preprocessing numbers.
-if (!isPreprocessingNumberBody(FileName[i]))
-  FileName[i] = '_';
-  }
+  if (CXXGlobalInits.empty())
+return;
 
+  // Include the filename in the symbol name. Including "sub_" matches gcc
+  // and makes sure these symbols appear lexicographically behind the symbols
+  // with priority emitted above.
+  SmallString<128> FileName;
   llvm::Function *Fn = CreateGlobalInitOrDestructFunction(
-  FTy, llvm::Twine("_GLOBAL__sub_I_", FileName), FI);
+  FTy,
+  llvm::Twine("_GLOBAL__sub_I_",
+  getTransformedFileName(getModule(), FileName)),
+  FI);
 
   CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, CXXGlobalInits);
   AddGlobalCtor(Fn);
@@ -631,6 +644,7 @@
 
   CodeGenFunction(*this).GenerateCXXGlobalDtorsFunc(Fn, CXXGlobalDtors);
   AddGlobalDtor(Fn);
+  CXXGlobalDtors.clear();
 }
 
 /// Emit the code necessary to initialize the given global variable.


Index: clang/lib/CodeGen/CGDeclCXX.cpp
===
--- clang/lib/CodeGen/CGDeclCXX.cpp
+++ clang/lib/CodeGen/CGDeclCXX.cpp
@@ -533,6 +533,23 @@
   CXXThreadLocals.clear();
 }
 
+static StringRef getTransformedFileName(llvm::Module &M,
+SmallString<128> &FileName) {
+  FileName = llvm::sys::path::filename(M.getName());
+
+  if (FileName.empty())
+FileName = "";
+
+  for (size_t i = 0; i < FileName.size(); ++i) {
+// Replace everything that's not [a-zA-Z0-9._] with a _. This set happens
+// to be the set of C preprocessing numbers.
+if (!isPreprocessingNumberBody(FileName[i]))
+  FileName[i] = '_';
+  }
+
+  return FileName;
+}
+
 void
 CodeGenModule::EmitCXXGlobalInitFunc() {
   while (!CXXGlobalInits.empty() && !CXXGlobalInits.back())
@@ -577,22 +594,18 @@
 PrioritizedCXXGlobalInits.clear();
   }
 
-  // Include the filename in the symbol name. Including "sub_" matches gcc and
-  // makes sure these symbols appear lexicographically behind the symbols with
-  // priority emitted above.
-  SmallString<128> FileName = llvm::sys::path::filename(getModule().getName());
-  if (FileName.empty())
-FileName = "";
-
-  for (size_t i = 0; i < FileName.size(); ++i) {
-// Replace everything that's not [a-zA-Z0-9._] with a _. This set happens
-// to be the set of C preprocessing numbers.
-if (!isPreprocessingNumberBody(FileName[i]))
-  FileName[i] = '_';
-  }
+  if (CXXGlobalInits.empty())
+return;
 
+  // Include the filename in the symbol name. Including "sub_" matches gcc
+  // and makes sure these symbols appear lexicographically behind the symbols
+  // with priority emitted above.
+  SmallString<128> FileName;
   llvm::Function *Fn = CreateGlobalInitOrDestructFunction(
-  FTy, llvm::Twine("_GLOBAL__sub_I_", FileName), FI);
+  FTy,
+  llvm::Twine("_GLOBAL__sub_I_",
+  getTransformedFileName(getModule(), FileName)),
+  FI);
 
   CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, CXXGlobalInits);
   AddGlobalCtor(Fn);
@@ -631,6 +644,7 @@
 
   CodeGenFunction(*this).GenerateCXXGlobalDtorsFunc(Fn, CXXGlobalDtors);
   AddGlobalDtor(Fn);
+  CXXGlobalDtors.clear();
 }
 
 /// Emit the code necessary to initialize the given global variab

[PATCH] D81972: [NFC] Cleanup of EmitCXXGlobalInitFunc() and EmitCXXGlobalDtorFunc()

2020-06-17 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L updated this revision to Diff 271486.
Xiangling_L marked 3 inline comments as done.
Xiangling_L added a comment.

Remove early return part;


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D81972/new/

https://reviews.llvm.org/D81972

Files:
  clang/lib/CodeGen/CGDeclCXX.cpp


Index: clang/lib/CodeGen/CGDeclCXX.cpp
===
--- clang/lib/CodeGen/CGDeclCXX.cpp
+++ clang/lib/CodeGen/CGDeclCXX.cpp
@@ -533,6 +533,23 @@
   CXXThreadLocals.clear();
 }
 
+static StringRef getTransformedFileName(llvm::Module &M,
+SmallString<128> &FileName) {
+  FileName = llvm::sys::path::filename(M.getName());
+
+  if (FileName.empty())
+FileName = "";
+
+  for (size_t i = 0; i < FileName.size(); ++i) {
+// Replace everything that's not [a-zA-Z0-9._] with a _. This set happens
+// to be the set of C preprocessing numbers.
+if (!isPreprocessingNumberBody(FileName[i]))
+  FileName[i] = '_';
+  }
+
+  return FileName;
+}
+
 void
 CodeGenModule::EmitCXXGlobalInitFunc() {
   while (!CXXGlobalInits.empty() && !CXXGlobalInits.back())
@@ -577,22 +594,15 @@
 PrioritizedCXXGlobalInits.clear();
   }
 
-  // Include the filename in the symbol name. Including "sub_" matches gcc and
-  // makes sure these symbols appear lexicographically behind the symbols with
-  // priority emitted above.
-  SmallString<128> FileName = llvm::sys::path::filename(getModule().getName());
-  if (FileName.empty())
-FileName = "";
-
-  for (size_t i = 0; i < FileName.size(); ++i) {
-// Replace everything that's not [a-zA-Z0-9._] with a _. This set happens
-// to be the set of C preprocessing numbers.
-if (!isPreprocessingNumberBody(FileName[i]))
-  FileName[i] = '_';
-  }
-
+  // Include the filename in the symbol name. Including "sub_" matches gcc
+  // and makes sure these symbols appear lexicographically behind the symbols
+  // with priority emitted above.
+  SmallString<128> FileName;
   llvm::Function *Fn = CreateGlobalInitOrDestructFunction(
-  FTy, llvm::Twine("_GLOBAL__sub_I_", FileName), FI);
+  FTy,
+  llvm::Twine("_GLOBAL__sub_I_",
+  getTransformedFileName(getModule(), FileName)),
+  FI);
 
   CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, CXXGlobalInits);
   AddGlobalCtor(Fn);
@@ -631,6 +641,7 @@
 
   CodeGenFunction(*this).GenerateCXXGlobalDtorsFunc(Fn, CXXGlobalDtors);
   AddGlobalDtor(Fn);
+  CXXGlobalDtors.clear();
 }
 
 /// Emit the code necessary to initialize the given global variable.


Index: clang/lib/CodeGen/CGDeclCXX.cpp
===
--- clang/lib/CodeGen/CGDeclCXX.cpp
+++ clang/lib/CodeGen/CGDeclCXX.cpp
@@ -533,6 +533,23 @@
   CXXThreadLocals.clear();
 }
 
+static StringRef getTransformedFileName(llvm::Module &M,
+SmallString<128> &FileName) {
+  FileName = llvm::sys::path::filename(M.getName());
+
+  if (FileName.empty())
+FileName = "";
+
+  for (size_t i = 0; i < FileName.size(); ++i) {
+// Replace everything that's not [a-zA-Z0-9._] with a _. This set happens
+// to be the set of C preprocessing numbers.
+if (!isPreprocessingNumberBody(FileName[i]))
+  FileName[i] = '_';
+  }
+
+  return FileName;
+}
+
 void
 CodeGenModule::EmitCXXGlobalInitFunc() {
   while (!CXXGlobalInits.empty() && !CXXGlobalInits.back())
@@ -577,22 +594,15 @@
 PrioritizedCXXGlobalInits.clear();
   }
 
-  // Include the filename in the symbol name. Including "sub_" matches gcc and
-  // makes sure these symbols appear lexicographically behind the symbols with
-  // priority emitted above.
-  SmallString<128> FileName = llvm::sys::path::filename(getModule().getName());
-  if (FileName.empty())
-FileName = "";
-
-  for (size_t i = 0; i < FileName.size(); ++i) {
-// Replace everything that's not [a-zA-Z0-9._] with a _. This set happens
-// to be the set of C preprocessing numbers.
-if (!isPreprocessingNumberBody(FileName[i]))
-  FileName[i] = '_';
-  }
-
+  // Include the filename in the symbol name. Including "sub_" matches gcc
+  // and makes sure these symbols appear lexicographically behind the symbols
+  // with priority emitted above.
+  SmallString<128> FileName;
   llvm::Function *Fn = CreateGlobalInitOrDestructFunction(
-  FTy, llvm::Twine("_GLOBAL__sub_I_", FileName), FI);
+  FTy,
+  llvm::Twine("_GLOBAL__sub_I_",
+  getTransformedFileName(getModule(), FileName)),
+  FI);
 
   CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, CXXGlobalInits);
   AddGlobalCtor(Fn);
@@ -631,6 +641,7 @@
 
   CodeGenFunction(*this).GenerateCXXGlobalDtorsFunc(Fn, CXXGlobalDtors);
   AddGlobalDtor(Fn);
+  CXXGlobalDtors.clear();
 }
 
 /// Emit the code necessary to initialize the given global variable.
___
cfe-commits mailing list

[PATCH] D81972: [NFC] Cleanup of EmitCXXGlobalInitFunc() and EmitCXXGlobalDtorFunc()

2020-06-17 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L added inline comments.



Comment at: clang/lib/CodeGen/CGDeclCXX.cpp:596
   }
 
+  // Include the filename in the symbol name. Including "sub_" matches gcc

jasonliu wrote:
> jasonliu wrote:
> > jasonliu wrote:
> > > I think this patch is missing what @hubert.reinterpretcast mentioned in 
> > > https://reviews.llvm.org/D74166?id=269900#inline-751064
> > > which is an early return like this:
> > > 
> > > ```
> > >  if (CXXGlobalInits.empty())
> > > return;
> > > ```
> > Please double check the above early return is desired though. It seems even 
> > when CXXGlobalInits is empty, `GenerateCXXGlobalInitFunc` is trying to do a 
> > lot of things with `Fn` passed in. Later, we also called 
> > `AddGlobalCtor(Fn)`. So a lot of behavior changes here, we want to make 
> > sure it's really 'NFC'.
> FYI,
> ```
> class test {
>   public:
> test();
> };
> test t1 __attribute__((init_priority (300)));
> ```
> Compile with `clang  -target x86_64-apple-darwin10   -emit-llvm `
> With this change, I guess we will not generate @_GLOBAL__sub_I_d.cpp(), and 
> also that function will not get added into @llvm.global_ctors.
> I'm not sure if we really need @_GLOBAL__sub_I_d.cpp() on that platform in 
> this case. But this change does not really qualify as NFC. 
> If we need to do this change, a test case is necessary, and we better ask 
> people who familiar with the platform to confirm it's a desired change. 
Thanks, I am gonna remove this part and keep it as a NFC patch.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D81972/new/

https://reviews.llvm.org/D81972



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D81972: [NFC] Cleanup of EmitCXXGlobalInitFunc() and EmitCXXGlobalDtorFunc()

2020-06-17 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L updated this revision to Diff 271492.
Xiangling_L added a comment.

Add the context to the patch;


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D81972/new/

https://reviews.llvm.org/D81972

Files:
  clang/lib/CodeGen/CGDeclCXX.cpp


Index: clang/lib/CodeGen/CGDeclCXX.cpp
===
--- clang/lib/CodeGen/CGDeclCXX.cpp
+++ clang/lib/CodeGen/CGDeclCXX.cpp
@@ -533,6 +533,23 @@
   CXXThreadLocals.clear();
 }
 
+static StringRef getTransformedFileName(llvm::Module &M,
+SmallString<128> &FileName) {
+  FileName = llvm::sys::path::filename(M.getName());
+
+  if (FileName.empty())
+FileName = "";
+
+  for (size_t i = 0; i < FileName.size(); ++i) {
+// Replace everything that's not [a-zA-Z0-9._] with a _. This set happens
+// to be the set of C preprocessing numbers.
+if (!isPreprocessingNumberBody(FileName[i]))
+  FileName[i] = '_';
+  }
+
+  return FileName;
+}
+
 void
 CodeGenModule::EmitCXXGlobalInitFunc() {
   while (!CXXGlobalInits.empty() && !CXXGlobalInits.back())
@@ -577,22 +594,15 @@
 PrioritizedCXXGlobalInits.clear();
   }
 
-  // Include the filename in the symbol name. Including "sub_" matches gcc and
-  // makes sure these symbols appear lexicographically behind the symbols with
-  // priority emitted above.
-  SmallString<128> FileName = llvm::sys::path::filename(getModule().getName());
-  if (FileName.empty())
-FileName = "";
-
-  for (size_t i = 0; i < FileName.size(); ++i) {
-// Replace everything that's not [a-zA-Z0-9._] with a _. This set happens
-// to be the set of C preprocessing numbers.
-if (!isPreprocessingNumberBody(FileName[i]))
-  FileName[i] = '_';
-  }
-
+  // Include the filename in the symbol name. Including "sub_" matches gcc
+  // and makes sure these symbols appear lexicographically behind the symbols
+  // with priority emitted above.
+  SmallString<128> FileName;
   llvm::Function *Fn = CreateGlobalInitOrDestructFunction(
-  FTy, llvm::Twine("_GLOBAL__sub_I_", FileName), FI);
+  FTy,
+  llvm::Twine("_GLOBAL__sub_I_",
+  getTransformedFileName(getModule(), FileName)),
+  FI);
 
   CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, CXXGlobalInits);
   AddGlobalCtor(Fn);
@@ -631,6 +641,7 @@
 
   CodeGenFunction(*this).GenerateCXXGlobalDtorsFunc(Fn, CXXGlobalDtors);
   AddGlobalDtor(Fn);
+  CXXGlobalDtors.clear();
 }
 
 /// Emit the code necessary to initialize the given global variable.


Index: clang/lib/CodeGen/CGDeclCXX.cpp
===
--- clang/lib/CodeGen/CGDeclCXX.cpp
+++ clang/lib/CodeGen/CGDeclCXX.cpp
@@ -533,6 +533,23 @@
   CXXThreadLocals.clear();
 }
 
+static StringRef getTransformedFileName(llvm::Module &M,
+SmallString<128> &FileName) {
+  FileName = llvm::sys::path::filename(M.getName());
+
+  if (FileName.empty())
+FileName = "";
+
+  for (size_t i = 0; i < FileName.size(); ++i) {
+// Replace everything that's not [a-zA-Z0-9._] with a _. This set happens
+// to be the set of C preprocessing numbers.
+if (!isPreprocessingNumberBody(FileName[i]))
+  FileName[i] = '_';
+  }
+
+  return FileName;
+}
+
 void
 CodeGenModule::EmitCXXGlobalInitFunc() {
   while (!CXXGlobalInits.empty() && !CXXGlobalInits.back())
@@ -577,22 +594,15 @@
 PrioritizedCXXGlobalInits.clear();
   }
 
-  // Include the filename in the symbol name. Including "sub_" matches gcc and
-  // makes sure these symbols appear lexicographically behind the symbols with
-  // priority emitted above.
-  SmallString<128> FileName = llvm::sys::path::filename(getModule().getName());
-  if (FileName.empty())
-FileName = "";
-
-  for (size_t i = 0; i < FileName.size(); ++i) {
-// Replace everything that's not [a-zA-Z0-9._] with a _. This set happens
-// to be the set of C preprocessing numbers.
-if (!isPreprocessingNumberBody(FileName[i]))
-  FileName[i] = '_';
-  }
-
+  // Include the filename in the symbol name. Including "sub_" matches gcc
+  // and makes sure these symbols appear lexicographically behind the symbols
+  // with priority emitted above.
+  SmallString<128> FileName;
   llvm::Function *Fn = CreateGlobalInitOrDestructFunction(
-  FTy, llvm::Twine("_GLOBAL__sub_I_", FileName), FI);
+  FTy,
+  llvm::Twine("_GLOBAL__sub_I_",
+  getTransformedFileName(getModule(), FileName)),
+  FI);
 
   CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, CXXGlobalInits);
   AddGlobalCtor(Fn);
@@ -631,6 +641,7 @@
 
   CodeGenFunction(*this).GenerateCXXGlobalDtorsFunc(Fn, CXXGlobalDtors);
   AddGlobalDtor(Fn);
+  CXXGlobalDtors.clear();
 }
 
 /// Emit the code necessary to initialize the given global variable.
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-c

[PATCH] D74166: [AIX][Frontend] Static init implementation for AIX considering no priority

2020-06-17 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L added inline comments.



Comment at: clang/lib/CodeGen/CGDeclCXX.cpp:708
+" based on strong external symbols");
+  GlobalUniqueModuleId = GlobalUniqueModuleId.substr(1);
+}

jasonliu wrote:
> Correct me if I'm wrong...
> `GlobalUniqueModuleId` will always get “initialized" in 
> `EmitCXXGlobalInitFunc`. And `EmitCXXGlobalInitFunc` will always run before 
> `EmitCXXGlobalCleanUpFunc` in `CodeGenModule::Release()`. So in theory, we do 
> not need to initialize it again in here. 
> If we could not `assert (!GlobalUniqueModuleId.empty())` here, that tells me 
> in `EmitCXXGlobalInitFunc` we effectively get an empty string after 
> `GlobalUniqueModuleId = GlobalUniqueModuleId.substr(1);`. So something is not 
> right?
Actually `GlobalUniqueModuleId` will not always get “initialized" in 
`EmitCXXGlobalInitFunc`. In some cases, only __sterm will be generated for the 
var decl.
e.g.
The static local variable won't be inited before main() but when called at the 
first time.
```
struct Test4 {
  Test4();
~Test4();
  };

  void f() {
static Test4 staticLocal;
  }

```



Comment at: clang/test/CodeGen/static-init.cpp:142
+
+// CHECK: ; Function Attrs: noinline nounwind
+// CHECK: define internal void @__finalize__ZZN5test41fEvE11staticLocal() #0 {

jasonliu wrote:
> Is checking this Attrs necessary?
I missed to delete this line. Thanks for pointing it out.



Comment at: clang/test/CodeGen/static-init.cpp:157
+
+// CHECK: define void 
@__sinit8000_clang_1145401da454a7baad10bfe313c46638() #5 {
+// CHECK: entry:

jasonliu wrote:
> I think we used to have dso_local marked on sinit and sterm function in 
> previous diff. Now they are gone. What's the reason for removing them?
`dso_local` affects calls to the function in terms of how the compiler will do 
the optimization on the call. Since we won't be generating any calls to the 
function (the linker arranges for the calls to happen indirectly), marking them 
dso_local does not help any. So I think it doesn't really matter if we put 
`dso_local` here.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D74166/new/

https://reviews.llvm.org/D74166



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D74166: [AIX][Frontend] Static init implementation for AIX considering no priority

2020-06-17 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L updated this revision to Diff 271550.
Xiangling_L marked 11 inline comments as done.
Xiangling_L edited the summary of this revision.
Xiangling_L added a comment.
Herald added a subscriber: jfb.

Remove trailing spaces;
Update the testcase;
Adjust the EmitGuardedInitBranch function;


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D74166/new/

https://reviews.llvm.org/D74166

Files:
  clang/include/clang/AST/Mangle.h
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/CodeGen/CGCXXABI.h
  clang/lib/CodeGen/CGDeclCXX.cpp
  clang/lib/CodeGen/CGOpenMPRuntime.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/CodeGen/CodeGenModule.h
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/lib/CodeGen/MicrosoftCXXABI.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/CodeGen/aix-constructor-attribute.cpp
  clang/test/CodeGen/aix-destructor-attribute.cpp
  clang/test/CodeGen/aix-init-priority-attribute.cpp
  clang/test/CodeGen/static-init.cpp
  clang/test/CodeGenCXX/aix-static-init.cpp

Index: clang/test/CodeGenCXX/aix-static-init.cpp
===
--- /dev/null
+++ clang/test/CodeGenCXX/aix-static-init.cpp
@@ -0,0 +1,193 @@
+// RUN: %clang_cc1 -triple powerpc-ibm-aix-xcoff -S -emit-llvm -x c++ \
+// RUN: -fno-use-cxa-atexit -std=c++2a < %s | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK32 %s
+
+// RUN: %clang_cc1 -triple powerpc64-ibm-aix-xcoff -S -emit-llvm -x c++ \
+// RUN: -fno-use-cxa-atexit -std=c++2a < %s | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK64 %s
+
+namespace test1 {
+  struct Test1 {
+Test1();
+~Test1();
+  } t1, t2;
+} // namespace test1
+
+namespace test2 {
+  int foo() { return 3; }
+  int x = foo();
+} // namespace test2
+
+namespace test3 {
+  struct Test3 {
+constexpr Test3() {};
+~Test3() {};
+  };
+
+  constinit Test3 t;
+} // namespace test3
+
+namespace test4 {
+  struct Test4 {
+Test4();
+~Test4();
+  };
+
+  void f() {
+static Test4 staticLocal;
+  }
+} // namespace test4
+
+// CHECK: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @__sinit8000_clang_1145401da454a7baad10bfe313c46638, i8* null }]
+// CHECK: @llvm.global_dtors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @__sterm8000_clang_1145401da454a7baad10bfe313c46638, i8* null }]
+
+// CHECK: define internal void @__cxx_global_var_init() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   call void @_ZN5test15Test1C1Ev(%"struct.test1::Test1"* @_ZN5test12t1E)
+// CHECK:   %0 = call i32 @atexit(void ()* @__dtor__ZN5test12t1E)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__dtor__ZN5test12t1E() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   call void @_ZN5test15Test1D1Ev(%"struct.test1::Test1"* @_ZN5test12t1E)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: declare i32 @atexit(void ()*)
+
+// CHECK: define internal void @__finalize__ZN5test12t1E() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   %0 = call i32 @unatexit(void ()* @__dtor__ZN5test12t1E)
+// CHECK:   %needs_destruct = icmp eq i32 %0, 0
+// CHECK:   br i1 %needs_destruct, label %destruct.call, label %destruct.end
+
+// CHECK: destruct.call:
+// CHECK:   call void @__dtor__ZN5test12t1E()
+// CHECK:   br label %destruct.end
+
+// CHECK: destruct.end:
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: declare i32 @unatexit(void ()*)
+
+// CHECK: define internal void @__cxx_global_var_init.1() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   call void @_ZN5test15Test1C1Ev(%"struct.test1::Test1"* @_ZN5test12t2E)
+// CHECK:   %0 = call i32 @atexit(void ()* @__dtor__ZN5test12t2E)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__dtor__ZN5test12t2E() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   call void @_ZN5test15Test1D1Ev(%"struct.test1::Test1"* @_ZN5test12t2E)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__finalize__ZN5test12t2E() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   %0 = call i32 @unatexit(void ()* @__dtor__ZN5test12t2E)
+// CHECK:   %needs_destruct = icmp eq i32 %0, 0
+// CHECK:   br i1 %needs_destruct, label %destruct.call, label %destruct.end
+
+// CHECK: destruct.call:
+// CHECK:   call void @__dtor__ZN5test12t2E()
+// CHECK:   br label %destruct.end
+
+// CHECK: destruct.end:
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__cxx_global_var_init.2() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK32: %call = call i32 @_ZN5test23fooEv()
+// CHECK64: %call = call signext i32 @_ZN5test23fooEv()
+// CHECK:   store i32 %call, i32* @_ZN5test21xE
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__cxx_global_var_init.3() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   %0 = call i32 @atexit(void ()* @__dtor__ZN5test31tE)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal voi

[PATCH] D81972: [NFC] Cleanup of EmitCXXGlobalInitFunc() and EmitCXXGlobalDtorFunc()

2020-06-18 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L updated this revision to Diff 271661.
Xiangling_L marked 2 inline comments as done.
Xiangling_L added a comment.

Address comments;


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D81972/new/

https://reviews.llvm.org/D81972

Files:
  clang/lib/CodeGen/CGDeclCXX.cpp


Index: clang/lib/CodeGen/CGDeclCXX.cpp
===
--- clang/lib/CodeGen/CGDeclCXX.cpp
+++ clang/lib/CodeGen/CGDeclCXX.cpp
@@ -533,6 +533,22 @@
   CXXThreadLocals.clear();
 }
 
+static SmallString<128> getTransformedFileName(llvm::Module &M) {
+  SmallString<128> FileName = llvm::sys::path::filename(M.getName());
+
+  if (FileName.empty())
+FileName = "";
+
+  for (size_t i = 0; i < FileName.size(); ++i) {
+// Replace everything that's not [a-zA-Z0-9._] with a _. This set happens
+// to be the set of C preprocessing numbers.
+if (!isPreprocessingNumberBody(FileName[i]))
+  FileName[i] = '_';
+  }
+
+  return FileName;
+}
+
 void
 CodeGenModule::EmitCXXGlobalInitFunc() {
   while (!CXXGlobalInits.empty() && !CXXGlobalInits.back())
@@ -577,22 +593,12 @@
 PrioritizedCXXGlobalInits.clear();
   }
 
-  // Include the filename in the symbol name. Including "sub_" matches gcc and
-  // makes sure these symbols appear lexicographically behind the symbols with
-  // priority emitted above.
-  SmallString<128> FileName = llvm::sys::path::filename(getModule().getName());
-  if (FileName.empty())
-FileName = "";
-
-  for (size_t i = 0; i < FileName.size(); ++i) {
-// Replace everything that's not [a-zA-Z0-9._] with a _. This set happens
-// to be the set of C preprocessing numbers.
-if (!isPreprocessingNumberBody(FileName[i]))
-  FileName[i] = '_';
-  }
-
+  // Include the filename in the symbol name. Including "sub_" matches gcc
+  // and makes sure these symbols appear lexicographically behind the symbols
+  // with priority emitted above.
   llvm::Function *Fn = CreateGlobalInitOrDestructFunction(
-  FTy, llvm::Twine("_GLOBAL__sub_I_", FileName), FI);
+  FTy,
+  llvm::Twine("_GLOBAL__sub_I_", getTransformedFileName(getModule())), FI);
 
   CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, CXXGlobalInits);
   AddGlobalCtor(Fn);
@@ -631,6 +637,7 @@
 
   CodeGenFunction(*this).GenerateCXXGlobalDtorsFunc(Fn, CXXGlobalDtors);
   AddGlobalDtor(Fn);
+  CXXGlobalDtors.clear();
 }
 
 /// Emit the code necessary to initialize the given global variable.


Index: clang/lib/CodeGen/CGDeclCXX.cpp
===
--- clang/lib/CodeGen/CGDeclCXX.cpp
+++ clang/lib/CodeGen/CGDeclCXX.cpp
@@ -533,6 +533,22 @@
   CXXThreadLocals.clear();
 }
 
+static SmallString<128> getTransformedFileName(llvm::Module &M) {
+  SmallString<128> FileName = llvm::sys::path::filename(M.getName());
+
+  if (FileName.empty())
+FileName = "";
+
+  for (size_t i = 0; i < FileName.size(); ++i) {
+// Replace everything that's not [a-zA-Z0-9._] with a _. This set happens
+// to be the set of C preprocessing numbers.
+if (!isPreprocessingNumberBody(FileName[i]))
+  FileName[i] = '_';
+  }
+
+  return FileName;
+}
+
 void
 CodeGenModule::EmitCXXGlobalInitFunc() {
   while (!CXXGlobalInits.empty() && !CXXGlobalInits.back())
@@ -577,22 +593,12 @@
 PrioritizedCXXGlobalInits.clear();
   }
 
-  // Include the filename in the symbol name. Including "sub_" matches gcc and
-  // makes sure these symbols appear lexicographically behind the symbols with
-  // priority emitted above.
-  SmallString<128> FileName = llvm::sys::path::filename(getModule().getName());
-  if (FileName.empty())
-FileName = "";
-
-  for (size_t i = 0; i < FileName.size(); ++i) {
-// Replace everything that's not [a-zA-Z0-9._] with a _. This set happens
-// to be the set of C preprocessing numbers.
-if (!isPreprocessingNumberBody(FileName[i]))
-  FileName[i] = '_';
-  }
-
+  // Include the filename in the symbol name. Including "sub_" matches gcc
+  // and makes sure these symbols appear lexicographically behind the symbols
+  // with priority emitted above.
   llvm::Function *Fn = CreateGlobalInitOrDestructFunction(
-  FTy, llvm::Twine("_GLOBAL__sub_I_", FileName), FI);
+  FTy,
+  llvm::Twine("_GLOBAL__sub_I_", getTransformedFileName(getModule())), FI);
 
   CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, CXXGlobalInits);
   AddGlobalCtor(Fn);
@@ -631,6 +637,7 @@
 
   CodeGenFunction(*this).GenerateCXXGlobalDtorsFunc(Fn, CXXGlobalDtors);
   AddGlobalDtor(Fn);
+  CXXGlobalDtors.clear();
 }
 
 /// Emit the code necessary to initialize the given global variable.
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D74166: [AIX][Frontend] Static init implementation for AIX considering no priority

2020-06-18 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L updated this revision to Diff 271664.
Xiangling_L marked an inline comment as done.
Xiangling_L added a comment.

Adjust the patch corresponding to D81972 ;


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D74166/new/

https://reviews.llvm.org/D74166

Files:
  clang/include/clang/AST/Mangle.h
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/CodeGen/CGCXXABI.h
  clang/lib/CodeGen/CGDeclCXX.cpp
  clang/lib/CodeGen/CGOpenMPRuntime.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/CodeGen/CodeGenModule.h
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/lib/CodeGen/MicrosoftCXXABI.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/CodeGen/aix-constructor-attribute.cpp
  clang/test/CodeGen/aix-destructor-attribute.cpp
  clang/test/CodeGen/aix-init-priority-attribute.cpp
  clang/test/CodeGen/static-init.cpp
  clang/test/CodeGenCXX/aix-static-init.cpp

Index: clang/test/CodeGenCXX/aix-static-init.cpp
===
--- /dev/null
+++ clang/test/CodeGenCXX/aix-static-init.cpp
@@ -0,0 +1,193 @@
+// RUN: %clang_cc1 -triple powerpc-ibm-aix-xcoff -S -emit-llvm -x c++ \
+// RUN: -fno-use-cxa-atexit -std=c++2a < %s | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK32 %s
+
+// RUN: %clang_cc1 -triple powerpc64-ibm-aix-xcoff -S -emit-llvm -x c++ \
+// RUN: -fno-use-cxa-atexit -std=c++2a < %s | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK64 %s
+
+namespace test1 {
+  struct Test1 {
+Test1();
+~Test1();
+  } t1, t2;
+} // namespace test1
+
+namespace test2 {
+  int foo() { return 3; }
+  int x = foo();
+} // namespace test2
+
+namespace test3 {
+  struct Test3 {
+constexpr Test3() {};
+~Test3() {};
+  };
+
+  constinit Test3 t;
+} // namespace test3
+
+namespace test4 {
+  struct Test4 {
+Test4();
+~Test4();
+  };
+
+  void f() {
+static Test4 staticLocal;
+  }
+} // namespace test4
+
+// CHECK: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @__sinit8000_clang_1145401da454a7baad10bfe313c46638, i8* null }]
+// CHECK: @llvm.global_dtors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @__sterm8000_clang_1145401da454a7baad10bfe313c46638, i8* null }]
+
+// CHECK: define internal void @__cxx_global_var_init() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   call void @_ZN5test15Test1C1Ev(%"struct.test1::Test1"* @_ZN5test12t1E)
+// CHECK:   %0 = call i32 @atexit(void ()* @__dtor__ZN5test12t1E)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__dtor__ZN5test12t1E() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   call void @_ZN5test15Test1D1Ev(%"struct.test1::Test1"* @_ZN5test12t1E)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: declare i32 @atexit(void ()*)
+
+// CHECK: define internal void @__finalize__ZN5test12t1E() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   %0 = call i32 @unatexit(void ()* @__dtor__ZN5test12t1E)
+// CHECK:   %needs_destruct = icmp eq i32 %0, 0
+// CHECK:   br i1 %needs_destruct, label %destruct.call, label %destruct.end
+
+// CHECK: destruct.call:
+// CHECK:   call void @__dtor__ZN5test12t1E()
+// CHECK:   br label %destruct.end
+
+// CHECK: destruct.end:
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: declare i32 @unatexit(void ()*)
+
+// CHECK: define internal void @__cxx_global_var_init.1() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   call void @_ZN5test15Test1C1Ev(%"struct.test1::Test1"* @_ZN5test12t2E)
+// CHECK:   %0 = call i32 @atexit(void ()* @__dtor__ZN5test12t2E)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__dtor__ZN5test12t2E() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   call void @_ZN5test15Test1D1Ev(%"struct.test1::Test1"* @_ZN5test12t2E)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__finalize__ZN5test12t2E() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   %0 = call i32 @unatexit(void ()* @__dtor__ZN5test12t2E)
+// CHECK:   %needs_destruct = icmp eq i32 %0, 0
+// CHECK:   br i1 %needs_destruct, label %destruct.call, label %destruct.end
+
+// CHECK: destruct.call:
+// CHECK:   call void @__dtor__ZN5test12t2E()
+// CHECK:   br label %destruct.end
+
+// CHECK: destruct.end:
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__cxx_global_var_init.2() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK32: %call = call i32 @_ZN5test23fooEv()
+// CHECK64: %call = call signext i32 @_ZN5test23fooEv()
+// CHECK:   store i32 %call, i32* @_ZN5test21xE
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__cxx_global_var_init.3() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   %0 = call i32 @atexit(void ()* @__dtor__ZN5test31tE)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__dtor__ZN5test31tE() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   call void @_ZN5test

[PATCH] D74166: [AIX][Frontend] Static init implementation for AIX considering no priority

2020-06-18 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L updated this revision to Diff 271668.
Xiangling_L added a comment.

Fix the previous bad version;


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D74166/new/

https://reviews.llvm.org/D74166

Files:
  clang/include/clang/AST/Mangle.h
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/CodeGen/CGCXXABI.h
  clang/lib/CodeGen/CGDeclCXX.cpp
  clang/lib/CodeGen/CGOpenMPRuntime.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/CodeGen/CodeGenModule.h
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/lib/CodeGen/MicrosoftCXXABI.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/CodeGen/aix-constructor-attribute.cpp
  clang/test/CodeGen/aix-destructor-attribute.cpp
  clang/test/CodeGen/aix-init-priority-attribute.cpp
  clang/test/CodeGen/static-init.cpp
  clang/test/CodeGenCXX/aix-static-init.cpp

Index: clang/test/CodeGenCXX/aix-static-init.cpp
===
--- /dev/null
+++ clang/test/CodeGenCXX/aix-static-init.cpp
@@ -0,0 +1,193 @@
+// RUN: %clang_cc1 -triple powerpc-ibm-aix-xcoff -S -emit-llvm -x c++ \
+// RUN: -fno-use-cxa-atexit -std=c++2a < %s | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK32 %s
+
+// RUN: %clang_cc1 -triple powerpc64-ibm-aix-xcoff -S -emit-llvm -x c++ \
+// RUN: -fno-use-cxa-atexit -std=c++2a < %s | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK64 %s
+
+namespace test1 {
+  struct Test1 {
+Test1();
+~Test1();
+  } t1, t2;
+} // namespace test1
+
+namespace test2 {
+  int foo() { return 3; }
+  int x = foo();
+} // namespace test2
+
+namespace test3 {
+  struct Test3 {
+constexpr Test3() {};
+~Test3() {};
+  };
+
+  constinit Test3 t;
+} // namespace test3
+
+namespace test4 {
+  struct Test4 {
+Test4();
+~Test4();
+  };
+
+  void f() {
+static Test4 staticLocal;
+  }
+} // namespace test4
+
+// CHECK: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @__sinit8000_clang_1145401da454a7baad10bfe313c46638, i8* null }]
+// CHECK: @llvm.global_dtors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @__sterm8000_clang_1145401da454a7baad10bfe313c46638, i8* null }]
+
+// CHECK: define internal void @__cxx_global_var_init() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   call void @_ZN5test15Test1C1Ev(%"struct.test1::Test1"* @_ZN5test12t1E)
+// CHECK:   %0 = call i32 @atexit(void ()* @__dtor__ZN5test12t1E)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__dtor__ZN5test12t1E() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   call void @_ZN5test15Test1D1Ev(%"struct.test1::Test1"* @_ZN5test12t1E)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: declare i32 @atexit(void ()*)
+
+// CHECK: define internal void @__finalize__ZN5test12t1E() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   %0 = call i32 @unatexit(void ()* @__dtor__ZN5test12t1E)
+// CHECK:   %needs_destruct = icmp eq i32 %0, 0
+// CHECK:   br i1 %needs_destruct, label %destruct.call, label %destruct.end
+
+// CHECK: destruct.call:
+// CHECK:   call void @__dtor__ZN5test12t1E()
+// CHECK:   br label %destruct.end
+
+// CHECK: destruct.end:
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: declare i32 @unatexit(void ()*)
+
+// CHECK: define internal void @__cxx_global_var_init.1() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   call void @_ZN5test15Test1C1Ev(%"struct.test1::Test1"* @_ZN5test12t2E)
+// CHECK:   %0 = call i32 @atexit(void ()* @__dtor__ZN5test12t2E)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__dtor__ZN5test12t2E() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   call void @_ZN5test15Test1D1Ev(%"struct.test1::Test1"* @_ZN5test12t2E)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__finalize__ZN5test12t2E() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   %0 = call i32 @unatexit(void ()* @__dtor__ZN5test12t2E)
+// CHECK:   %needs_destruct = icmp eq i32 %0, 0
+// CHECK:   br i1 %needs_destruct, label %destruct.call, label %destruct.end
+
+// CHECK: destruct.call:
+// CHECK:   call void @__dtor__ZN5test12t2E()
+// CHECK:   br label %destruct.end
+
+// CHECK: destruct.end:
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__cxx_global_var_init.2() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK32: %call = call i32 @_ZN5test23fooEv()
+// CHECK64: %call = call signext i32 @_ZN5test23fooEv()
+// CHECK:   store i32 %call, i32* @_ZN5test21xE
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__cxx_global_var_init.3() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   %0 = call i32 @atexit(void ()* @__dtor__ZN5test31tE)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__dtor__ZN5test31tE() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   call void @_ZN5test35Test3D1Ev(%"struct.test3::Test3"* @_ZN5test31tE)
+// CHECK:   ret void
+// CHECK: }
+
+// 

[PATCH] D79719: [AIX] Implement AIX special alignment rule about double/long double

2020-07-02 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L marked an inline comment as done.
Xiangling_L added inline comments.



Comment at: clang/test/Layout/aix-double-struct-member.cpp:1
+// RUN: %clang_cc1 -emit-llvm-only -triple powerpc-ibm-aix-xcoff \
+// RUN: -fdump-record-layouts -fsyntax-only %s 2>/dev/null | \

hubert.reinterpretcast wrote:
> I am concerned that none of the tests actually create an instance of the 
> classes under test and check the alignment (or related adjustments) in the 
> IR. That is, we set up the preferred alignment value but don't check that we 
> use it where we should.
> 
> As it is, it seems array new/delete has problems:
> ```
> #include 
> extern "C" void *calloc(decltype(sizeof 0), decltype(sizeof 0));
> extern "C" void free(void *);
> extern "C" int printf(const char *, ...);
> 
> extern void *allocated_ptr;
> extern decltype(sizeof 0) allocated_size;
> struct B {
>   double d;
>   ~B() {}
>   static void *operator new[](decltype(sizeof 0) sz);
>   static void operator delete[](void *p, decltype(sizeof 0) sz);
> };
> B *allocBp();
> 
> #ifdef ALLOCBP
> void *allocated_ptr;
> decltype(sizeof 0) allocated_size;
> void *B::operator new[](decltype(sizeof 0) sz) {
>   void *alloc = calloc(1u, allocated_size = sz);
>   printf("%p: %s\n", alloc, __PRETTY_FUNCTION__);
>   printf("%zu\n", sz);
>   return allocated_ptr = alloc;
> }
> void B::operator delete[](void *p, decltype(sizeof 0) sz) {
>   printf("%p: %s\n", p, __PRETTY_FUNCTION__);
>   printf("%zu\n", sz);
>   assert(sz == allocated_size);
>   assert(p == allocated_ptr);
>   free(p);
> }
> B *allocBp() { return new B[2]; }
> #endif
> 
> #ifdef MAIN
> int main(void) { delete[] allocBp(); }
> #endif
> ```
> 
> The `xlclang++` invocation from XL C/C++ generates padding before the 32-bit 
> `new[]` cookie. I'm not seeing that padding with this patch.
Thank. I will create more practical testcases as you mentioned in your concern. 
And regarding to `padding before the 32-bit new[] cookie` issue, I am wondering 
is that part of `power` alignment rule or what rules do we follow to generate 
this kind of padding?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79719/new/

https://reviews.llvm.org/D79719



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D79719: [AIX] Implement AIX special alignment rule about double/long double

2020-07-03 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L marked 5 inline comments as done.
Xiangling_L added inline comments.



Comment at: clang/test/Layout/aix-double-struct-member.cpp:1
+// RUN: %clang_cc1 -emit-llvm-only -triple powerpc-ibm-aix-xcoff \
+// RUN: -fdump-record-layouts -fsyntax-only %s 2>/dev/null | \

hubert.reinterpretcast wrote:
> Xiangling_L wrote:
> > hubert.reinterpretcast wrote:
> > > I am concerned that none of the tests actually create an instance of the 
> > > classes under test and check the alignment (or related adjustments) in 
> > > the IR. That is, we set up the preferred alignment value but don't check 
> > > that we use it where we should.
> > > 
> > > As it is, it seems array new/delete has problems:
> > > ```
> > > #include 
> > > extern "C" void *calloc(decltype(sizeof 0), decltype(sizeof 0));
> > > extern "C" void free(void *);
> > > extern "C" int printf(const char *, ...);
> > > 
> > > extern void *allocated_ptr;
> > > extern decltype(sizeof 0) allocated_size;
> > > struct B {
> > >   double d;
> > >   ~B() {}
> > >   static void *operator new[](decltype(sizeof 0) sz);
> > >   static void operator delete[](void *p, decltype(sizeof 0) sz);
> > > };
> > > B *allocBp();
> > > 
> > > #ifdef ALLOCBP
> > > void *allocated_ptr;
> > > decltype(sizeof 0) allocated_size;
> > > void *B::operator new[](decltype(sizeof 0) sz) {
> > >   void *alloc = calloc(1u, allocated_size = sz);
> > >   printf("%p: %s\n", alloc, __PRETTY_FUNCTION__);
> > >   printf("%zu\n", sz);
> > >   return allocated_ptr = alloc;
> > > }
> > > void B::operator delete[](void *p, decltype(sizeof 0) sz) {
> > >   printf("%p: %s\n", p, __PRETTY_FUNCTION__);
> > >   printf("%zu\n", sz);
> > >   assert(sz == allocated_size);
> > >   assert(p == allocated_ptr);
> > >   free(p);
> > > }
> > > B *allocBp() { return new B[2]; }
> > > #endif
> > > 
> > > #ifdef MAIN
> > > int main(void) { delete[] allocBp(); }
> > > #endif
> > > ```
> > > 
> > > The `xlclang++` invocation from XL C/C++ generates padding before the 
> > > 32-bit `new[]` cookie. I'm not seeing that padding with this patch.
> > Thank. I will create more practical testcases as you mentioned in your 
> > concern. And regarding to `padding before the 32-bit new[] cookie` issue, I 
> > am wondering is that part of `power` alignment rule or what rules do we 
> > follow to generate this kind of padding?
> The padding has to do with the alignment. The allocation function returns 
> 8-byte aligned memory. The 32-bit cookie takes 4 of the first 8 bytes. The 
> type's preferred alignment is 8, so there are 4 bytes of padding.
Regarding with checking the alignment where we use them, AFAIK the problematic 
cases include not only the `cookie padding` issue you mentioned here, but also 
the alignment of argument type, return type etc.

So I am wondering does it make sense to have them handled in a separate patch 
since this is already a big one? We can use this patch to implement the correct 
value of `__alignof` and `alignof` and use a second patch to handle the places 
where `we use them where we should`?



Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79719/new/

https://reviews.llvm.org/D79719



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D79719: [AIX] Implement AIX special alignment rule about double/long double

2020-07-06 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L marked 27 inline comments as done.
Xiangling_L added inline comments.



Comment at: clang/lib/AST/ASTContext.cpp:2424
+  (T->isSpecificBuiltinType(BuiltinType::LongDouble) &&
+   Target->supportsAIXPowerAlignment()))
 // Don't increase the alignment if an alignment attribute was specified on 
a

hubert.reinterpretcast wrote:
> hubert.reinterpretcast wrote:
> > Xiangling_L wrote:
> > > hubert.reinterpretcast wrote:
> > > > Does `supportsAIXPowerAlignment` express the condition we want to check 
> > > > here? That might be true for an implementation operating with `mac68k` 
> > > > alignment rules.
> > > Yeah, `supportsAIXPowerAlignment` cannot separate the preferred alignment 
> > > of double, long double between `power/natural` and `mac68k` alignment 
> > > rules. But I noticed that currently, AIX target on wyvern or XL don't 
> > > support `mac68k` , so maybe we should leave further changes to the patch 
> > > which is gonna implement `mac68k` alignment rules? The possible solution 
> > > I am thinking is we can add checking if the decl has `AlignMac68kAttr` 
> > > into query to separate things out.
> > > 
> > > Another thing is that once we start supporting mac68k alignment rule(if 
> > > we will), should we also change the ABI align values as well? (e.g. for 
> > > double, it should be 2 instead)
> > If the "base state" is AIX `power` alignment for a platform, I suggest that 
> > the name be `defaultsToAIXPowerAlignment`.
> This last question about the ABI align values is relevant to considerations 
> for `natural` alignment support as well. More generally, the question is 
> whether the "minimum alignment" of the type in a context subject to 
> alternative alignment rules is altered to match said alignment rule. This is 
> observable via the diagnostic associated with C++11 alignment specifiers.
> 
> The existing behaviour of `mac68k` alignment suggests that the "minimum 
> alignment" is context-free.
> 
> ```
> #pragma options align=mac68k
> struct Q {
>   double x alignas(2);  // expected-error {{less than minimum alignment}}
> };
> #pragma options align=reset
> ```
> 
> Compiler Explorer link: https://godbolt.org/z/9NM5_-
Thank you for your explanation.



Comment at: clang/lib/AST/RecordLayoutBuilder.cpp:1885
+  Context.getBaseElementType(CTy->getElementType())
+  ->getAs())
+if (BTy->getKind() == BuiltinType::Double ||

hubert.reinterpretcast wrote:
> I believe `castAs` should be expected to succeed here.
`castAs` is not declared in current context, do we really want to use it by 
introducing one more header?



Comment at: clang/lib/AST/RecordLayoutBuilder.cpp:1898
+} else if (const RecordType *RT = D->getType()
+  ->getBaseElementTypeUnsafe()
+  ->getAs()) {

hubert.reinterpretcast wrote:
> Is there a reason to use `getBaseElementTypeUnsafe` for this case and 
> `Context.getBaseElementType` for the other ones? Also, it would make sense to 
> factor out the array-type considerations once at the top of the if-else chain 
> instead of doing so in each alternative.
Sorry, I didn't pay attention to the different versions of `getBaseElementType` 
functions here and I believe this part of code came from our old compiler's 
changesets. My understanding would be since type qualifiers are not very 
meaningful in our case and `getBaseElementTypeUnsafe()` is more efficient than 
`getBaseElementType()`, we can use `getBaseElementTypeUnsafe()` all over the 
place instead.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79719/new/

https://reviews.llvm.org/D79719



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D79719: [AIX] Implement AIX special alignment rule about double/long double

2020-07-06 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L updated this revision to Diff 275728.
Xiangling_L marked 3 inline comments as done.
Xiangling_L added a comment.

Fixed -Wpacked warning issue;
Fixed EmptySubobjects related offset issue;
Fixed zero-extent array in a base class related issue;
Addressed other comments;


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79719/new/

https://reviews.llvm.org/D79719

Files:
  clang/include/clang/AST/RecordLayout.h
  clang/include/clang/Basic/TargetInfo.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/RecordLayout.cpp
  clang/lib/AST/RecordLayoutBuilder.cpp
  clang/lib/Basic/Targets/OSTargets.h
  clang/lib/Basic/Targets/PPC.h
  clang/test/Layout/aix-Wpacked.cpp
  clang/test/Layout/aix-double-struct-member.cpp
  clang/test/Layout/aix-no-unique-address-with-double.cpp
  clang/test/Layout/aix-virtual-function-and-base-with-double.cpp

Index: clang/test/Layout/aix-virtual-function-and-base-with-double.cpp
===
--- /dev/null
+++ clang/test/Layout/aix-virtual-function-and-base-with-double.cpp
@@ -0,0 +1,112 @@
+// RUN: %clang_cc1 -emit-llvm-only -triple powerpc-ibm-aix-xcoff \
+// RUN: -fdump-record-layouts -fsyntax-only %s 2>/dev/null | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK32 %s
+
+// RUN: %clang_cc1 -emit-llvm-only -triple powerpc64-ibm-aix-xcoff \
+// RUN: -fdump-record-layouts -fsyntax-only %s 2>/dev/null | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK64 %s
+
+namespace test1 {
+struct A {
+  double d1;
+  virtual void boo() {}
+};
+
+struct B {
+  double d2;
+  A a;
+};
+
+struct C : public A {
+  double d3;
+};
+
+int i = sizeof(B);
+int j = sizeof(C);
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::A
+// CHECK-NEXT:0 |   (A vtable pointer)
+// CHECK32-NEXT:  4 |   double d1
+// CHECK32-NEXT:| [sizeof=12, dsize=12, align=4, preferredalign=4,
+// CHECK32-NEXT:|  nvsize=12, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:  8 |   double d1
+// CHECK64-NEXT:| [sizeof=16, dsize=16, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=16, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::B
+// CHECK-NEXT:0 |   double d2
+// CHECK-NEXT:8 |   struct test1::A a
+// CHECK-NEXT:8 | (A vtable pointer)
+// CHECK32-NEXT: 12 | double d1
+// CHECK32-NEXT:| [sizeof=24, dsize=20, align=4, preferredalign=8,
+// CHECK32-NEXT:|  nvsize=20, nvalign=4, preferrednvalign=8]
+// CHECK64-NEXT: 16 | double d1
+// CHECK64-NEXT:| [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=24, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::C
+// CHECK-NEXT:0 |   struct test1::A (primary base)
+// CHECK-NEXT:0 | (A vtable pointer)
+// CHECK32-NEXT:  4 | double d1
+// CHECK32-NEXT: 12 |   double d3
+// CHECK32-NEXT:| [sizeof=20, dsize=20, align=4, preferredalign=4,
+// CHECK32-NEXT:|  nvsize=20, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:  8 | double d1
+// CHECK64-NEXT: 16 |   double d3
+// CHECK64-NEXT:| [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=24, nvalign=8, preferrednvalign=8]
+
+} // namespace test1
+
+namespace test2 {
+struct A {
+  long long l1;
+};
+
+struct B : public virtual A {
+  double d2;
+};
+
+#pragma pack(2)
+struct C : public virtual A {
+  double __attribute__((aligned(4))) d3;
+};
+
+int i = sizeof(B);
+int j = sizeof(C);
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::A
+// CHECK-NEXT:0 |   long long l1
+// CHECK-NEXT:  | [sizeof=8, dsize=8, align=8, preferredalign=8,
+// CHECK-NEXT:  |  nvsize=8, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::B
+// CHECK-NEXT:0 |   (B vtable pointer)
+// CHECK32-NEXT:  4 |   double d2
+// CHECK64-NEXT:  8 |   double d2
+// CHECK-NEXT:   16 |   struct test2::A (virtual base)
+// CHECK-NEXT:   16 | long long l1
+// CHECK-NEXT:  | [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK32-NEXT:|  nvsize=12, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:|  nvsize=16, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::C
+// CHECK-NEXT:0 |   (C vtable pointer)
+// CHECK32-NEXT:  4 |   double d3
+// CHECK32-NEXT: 12 |   struct test2::A (virtual base)
+// CHECK32-NEXT: 12 | long long l1
+// C

[PATCH] D79719: [AIX] Implement AIX special alignment rule about double/long double

2020-07-06 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L updated this revision to Diff 275840.
Xiangling_L marked 6 inline comments as done.
Xiangling_L added a comment.

Fixed the `typedef` related issues;
Added more testcases;


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79719/new/

https://reviews.llvm.org/D79719

Files:
  clang/include/clang/AST/RecordLayout.h
  clang/include/clang/Basic/TargetInfo.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/RecordLayout.cpp
  clang/lib/AST/RecordLayoutBuilder.cpp
  clang/lib/Basic/Targets/OSTargets.h
  clang/lib/Basic/Targets/PPC.h
  clang/test/Layout/aix-Wpacked.cpp
  clang/test/Layout/aix-double-struct-member.cpp
  clang/test/Layout/aix-no-unique-address-with-double.cpp
  clang/test/Layout/aix-power-alignment-typedef.cpp
  clang/test/Layout/aix-virtual-function-and-base-with-double.cpp

Index: clang/test/Layout/aix-virtual-function-and-base-with-double.cpp
===
--- /dev/null
+++ clang/test/Layout/aix-virtual-function-and-base-with-double.cpp
@@ -0,0 +1,112 @@
+// RUN: %clang_cc1 -emit-llvm-only -triple powerpc-ibm-aix-xcoff \
+// RUN: -fdump-record-layouts -fsyntax-only %s 2>/dev/null | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK32 %s
+
+// RUN: %clang_cc1 -emit-llvm-only -triple powerpc64-ibm-aix-xcoff \
+// RUN: -fdump-record-layouts -fsyntax-only %s 2>/dev/null | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK64 %s
+
+namespace test1 {
+struct A {
+  double d1;
+  virtual void boo() {}
+};
+
+struct B {
+  double d2;
+  A a;
+};
+
+struct C : public A {
+  double d3;
+};
+
+int i = sizeof(B);
+int j = sizeof(C);
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::A
+// CHECK-NEXT:0 |   (A vtable pointer)
+// CHECK32-NEXT:  4 |   double d1
+// CHECK32-NEXT:| [sizeof=12, dsize=12, align=4, preferredalign=4,
+// CHECK32-NEXT:|  nvsize=12, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:  8 |   double d1
+// CHECK64-NEXT:| [sizeof=16, dsize=16, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=16, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::B
+// CHECK-NEXT:0 |   double d2
+// CHECK-NEXT:8 |   struct test1::A a
+// CHECK-NEXT:8 | (A vtable pointer)
+// CHECK32-NEXT: 12 | double d1
+// CHECK32-NEXT:| [sizeof=24, dsize=20, align=4, preferredalign=8,
+// CHECK32-NEXT:|  nvsize=20, nvalign=4, preferrednvalign=8]
+// CHECK64-NEXT: 16 | double d1
+// CHECK64-NEXT:| [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=24, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::C
+// CHECK-NEXT:0 |   struct test1::A (primary base)
+// CHECK-NEXT:0 | (A vtable pointer)
+// CHECK32-NEXT:  4 | double d1
+// CHECK32-NEXT: 12 |   double d3
+// CHECK32-NEXT:| [sizeof=20, dsize=20, align=4, preferredalign=4,
+// CHECK32-NEXT:|  nvsize=20, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:  8 | double d1
+// CHECK64-NEXT: 16 |   double d3
+// CHECK64-NEXT:| [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=24, nvalign=8, preferrednvalign=8]
+
+} // namespace test1
+
+namespace test2 {
+struct A {
+  long long l1;
+};
+
+struct B : public virtual A {
+  double d2;
+};
+
+#pragma pack(2)
+struct C : public virtual A {
+  double __attribute__((aligned(4))) d3;
+};
+
+int i = sizeof(B);
+int j = sizeof(C);
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::A
+// CHECK-NEXT:0 |   long long l1
+// CHECK-NEXT:  | [sizeof=8, dsize=8, align=8, preferredalign=8,
+// CHECK-NEXT:  |  nvsize=8, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::B
+// CHECK-NEXT:0 |   (B vtable pointer)
+// CHECK32-NEXT:  4 |   double d2
+// CHECK64-NEXT:  8 |   double d2
+// CHECK-NEXT:   16 |   struct test2::A (virtual base)
+// CHECK-NEXT:   16 | long long l1
+// CHECK-NEXT:  | [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK32-NEXT:|  nvsize=12, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:|  nvsize=16, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::C
+// CHECK-NEXT:0 |   (C vtable pointer)
+// CHECK32-NEXT:  4 |   double d3
+// CHECK32-NEXT: 12 |   struct test2::A (virtual base)
+// CHECK32-NEXT: 12 | long long l1
+// CHECK32-NEXT:| [sizeof=20, dsize=2

[PATCH] D79719: [AIX] Implement AIX special alignment rule about double/long double

2020-07-06 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L added inline comments.



Comment at: clang/lib/AST/ASTContext.cpp:2409
+const RecordDecl *RD = RT->getDecl();
+return std::max(ABIAlign, static_cast(toBits(
+  getASTRecordLayout(RD).PreferredAlignment)));

hubert.reinterpretcast wrote:
> hubert.reinterpretcast wrote:
> > Please add a comment regarding the situations where the `ABIAlign` value is 
> > greater than the `PreferredAlignment` value. It may be appropriate to 
> > assert that, absent those cases, the `PreferredAlignment` value is at least 
> > that of `ABIAlign`.
> It does not appear that the maximum of the two values is the correct answer:
> ```
> struct C {
>   double x;
> } c;
> typedef struct C __attribute__((__aligned__(2))) CC;
> 
> CC cc;
> extern char x[__alignof__(cc)];
> extern char x[2]; // this is okay with IBM XL C/C++
> ```
> Please add a comment regarding the situations where the ABIAlign value is 
> greater than the PreferredAlignment value.

I added a `if` condition to guard the situation where `ABIAlign` should be 
returned instead of adding a comment. Please let me know if that is sufficient.



Comment at: clang/lib/AST/RecordLayoutBuilder.cpp:1888
+BTy->getKind() == BuiltinType::LongDouble) {
+  PreferredAlign = CharUnits::fromQuantity(8);
+}

hubert.reinterpretcast wrote:
> hubert.reinterpretcast wrote:
> > I believe an assertion that `PreferredAlign` was 4 would be appropriate.
> It seems that overriding the value should only be done after additional 
> checks:
> ```
> typedef double __attribute__((__aligned__(2))) Dbl;
> struct A {
>   Dbl x;
> } a;
> extern char x[__alignof__(a)];
> extern char x[2]; // this is okay with IBM XL C/C++
> ```
> 
> I am getting concerned that the logic here overlaps quite a bit with 
> `getPreferredTypeAlign` and refactoring to make the code here more common 
> with `getPreferredTypeAlign` is necessary.
Fixed the typedef related cases with my new changes, and the overlaps were not 
a lot as I expected. So I didn't do any refactoring yet. Please let me know if 
you still think it's necessary to refactor the code somehow.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79719/new/

https://reviews.llvm.org/D79719



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D79719: [AIX] Implement AIX special alignment rule about double/long double

2020-07-07 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L added inline comments.



Comment at: clang/lib/AST/RecordLayoutBuilder.cpp:1225
+   Context.getTargetInfo().getTriple().isPS4() ||
+   Context.getTargetInfo().getTriple().isOSAIX()))
+   ? CharUnits::One()

hubert.reinterpretcast wrote:
> Thanks; verified that this is correct with `xlclang++` from IBM XL C/C++ for 
> AIX with:
> ```
> struct A {
>   char x;
> };
> struct B {
>   int x;
> };
> struct __attribute__((__packed__)) C : A, B {} c;
> ```
> 
> Length is 5:
> ```
> [10]m   0x0004  .bss 1  externc
> [11]a4  0x0005   00 CM   RW00
> ```
> 
> @Xiangling_L, I suggest adding a case for this to the tests.
Sure, I will add it.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79719/new/

https://reviews.llvm.org/D79719



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D79719: [AIX] Implement AIX special alignment rule about double/long double

2020-07-07 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L updated this revision to Diff 276143.
Xiangling_L marked 14 inline comments as done.
Xiangling_L added a comment.

Fixed typedef issue on incomplete array field and add a test for it;
Added a test for where pack attribute on object also apply on base classes;
Addressed other comments;


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79719/new/

https://reviews.llvm.org/D79719

Files:
  clang/include/clang/AST/RecordLayout.h
  clang/include/clang/Basic/TargetInfo.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/RecordLayout.cpp
  clang/lib/AST/RecordLayoutBuilder.cpp
  clang/lib/Basic/Targets/OSTargets.h
  clang/lib/Basic/Targets/PPC.h
  clang/test/Layout/aix-Wpacked.cpp
  clang/test/Layout/aix-double-struct-member.cpp
  clang/test/Layout/aix-no-unique-address-with-double.cpp
  clang/test/Layout/aix-pack-attr-on-base.cpp
  clang/test/Layout/aix-power-alignment-typedef.cpp
  clang/test/Layout/aix-virtual-function-and-base-with-double.cpp

Index: clang/test/Layout/aix-virtual-function-and-base-with-double.cpp
===
--- /dev/null
+++ clang/test/Layout/aix-virtual-function-and-base-with-double.cpp
@@ -0,0 +1,112 @@
+// RUN: %clang_cc1 -emit-llvm-only -triple powerpc-ibm-aix-xcoff \
+// RUN: -fdump-record-layouts -fsyntax-only %s | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK32 %s
+
+// RUN: %clang_cc1 -emit-llvm-only -triple powerpc64-ibm-aix-xcoff \
+// RUN: -fdump-record-layouts -fsyntax-only %s | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK64 %s
+
+namespace test1 {
+struct A {
+  double d1;
+  virtual void boo() {}
+};
+
+struct B {
+  double d2;
+  A a;
+};
+
+struct C : public A {
+  double d3;
+};
+
+int i = sizeof(B);
+int j = sizeof(C);
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::A
+// CHECK-NEXT:0 |   (A vtable pointer)
+// CHECK32-NEXT:  4 |   double d1
+// CHECK32-NEXT:| [sizeof=12, dsize=12, align=4, preferredalign=4,
+// CHECK32-NEXT:|  nvsize=12, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:  8 |   double d1
+// CHECK64-NEXT:| [sizeof=16, dsize=16, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=16, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::B
+// CHECK-NEXT:0 |   double d2
+// CHECK-NEXT:8 |   struct test1::A a
+// CHECK-NEXT:8 | (A vtable pointer)
+// CHECK32-NEXT: 12 | double d1
+// CHECK32-NEXT:| [sizeof=24, dsize=20, align=4, preferredalign=8,
+// CHECK32-NEXT:|  nvsize=20, nvalign=4, preferrednvalign=8]
+// CHECK64-NEXT: 16 | double d1
+// CHECK64-NEXT:| [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=24, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::C
+// CHECK-NEXT:0 |   struct test1::A (primary base)
+// CHECK-NEXT:0 | (A vtable pointer)
+// CHECK32-NEXT:  4 | double d1
+// CHECK32-NEXT: 12 |   double d3
+// CHECK32-NEXT:| [sizeof=20, dsize=20, align=4, preferredalign=4,
+// CHECK32-NEXT:|  nvsize=20, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:  8 | double d1
+// CHECK64-NEXT: 16 |   double d3
+// CHECK64-NEXT:| [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=24, nvalign=8, preferrednvalign=8]
+
+} // namespace test1
+
+namespace test2 {
+struct A {
+  long long l1;
+};
+
+struct B : public virtual A {
+  double d2;
+};
+
+#pragma pack(2)
+struct C : public virtual A {
+  double __attribute__((aligned(4))) d3;
+};
+
+int i = sizeof(B);
+int j = sizeof(C);
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::A
+// CHECK-NEXT:0 |   long long l1
+// CHECK-NEXT:  | [sizeof=8, dsize=8, align=8, preferredalign=8,
+// CHECK-NEXT:  |  nvsize=8, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::B
+// CHECK-NEXT:0 |   (B vtable pointer)
+// CHECK32-NEXT:  4 |   double d2
+// CHECK64-NEXT:  8 |   double d2
+// CHECK-NEXT:   16 |   struct test2::A (virtual base)
+// CHECK-NEXT:   16 | long long l1
+// CHECK-NEXT:  | [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK32-NEXT:|  nvsize=12, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:|  nvsize=16, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::C
+// CHECK-NEXT:0 |   (C vtable pointer)
+// CHECK32-NEXT:  4 |   double d3
+// CHECK32-NEXT: 

[PATCH] D79719: [AIX] Implement AIX special alignment rule about double/long double

2020-07-08 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L marked 9 inline comments as done.
Xiangling_L added inline comments.



Comment at: clang/lib/AST/RecordLayoutBuilder.cpp:1796
+  bool FoundFirstNonOverlappingEmptyFieldToHandle =
+  DefaultsToAIXPowerAlignment && FieldOffset == CharUnits::Zero() &&
+  !HandledFirstNonOverlappingEmptyField && !IsOverlappingEmptyField;

hubert.reinterpretcast wrote:
> The condition is still more complex than I think it should be.
> 
> If we have found a "first" other-than-overlapping-empty-field, then we should 
> set `HandledFirstNonOverlappingEmptyField` to `true` for non-union cases.
> 
> If `HandledFirstNonOverlappingEmptyField` being `false` is not enough for 
> `FieldOffset == CharUnits::Zero()` to be true, then I think the correction 
> would be to set `HandledFirstNonOverlappingEmptyField` in more places.
> 
> I would like to remove the check on `FieldOffset == CharUnits::Zero()` from 
> here and instead have an assertion that 
> `!HandledFirstNonOverlappingEmptyField` implies `FieldOffset == 
> CharUnits::Zero()`.
> 
> Also, since we're managing `HandledFirstNonOverlappingEmptyField` in non-AIX 
> cases, we should remove the `DefaultsToAIXPowerAlignment` condition for what 
> is currently named `FoundFirstNonOverlappingEmptyFieldToHandle` (adjusting 
> uses of it as necessary) and rename 
> `FoundFirstNonOverlappingEmptyFieldToHandle` to 
> `FoundFirstNonOverlappingEmptyField`.
> Also, since we're managing HandledFirstNonOverlappingEmptyField in non-AIX 
> cases, we should remove the DefaultsToAIXPowerAlignment condition for what is 
> currently named FoundFirstNonOverlappingEmptyFieldToHandle 

I am not sure if we want to remove the `DefaultsToAIXPowerAlignment` condition 
and bother with maintaining correct status of 
`HandledFirstNonOverlappingEmptyField` for other targets.

We are actually claiming `HandledFirstNonOverlappingEmptyField` is an auxiliary 
flag used for AIX only in its definition comments.

Besides, if we do want to manage `HandledFirstNonOverlappingEmptyField` in 
non-AIX cases, I noticed that we have to set this flag to `true` somewhere for 
objective-C++ cases. 



Comment at: clang/lib/AST/RecordLayoutBuilder.cpp:1834
+TypeInfo TI = Context.getTypeInfo(D->getType());
+FieldAlign = Context.toCharUnitsFromBits(TI.Align);
+AlignIsRequired = TI.AlignIsRequired;

hubert.reinterpretcast wrote:
> I guess this works (we have a test for it), but the previous code made a 
> point to use the element type and not the array type (and the comment above 
> says we can't directly query `getTypeInfo` with the array type). 
> @Xiangling_L, can you confirm if the comment is out-of-date and update it?
I am sure `getTypeInfo` can recognize the element type for `IncompleteArray`. I 
will update the comments.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79719/new/

https://reviews.llvm.org/D79719



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D79719: [AIX] Implement AIX special alignment rule about double/long double

2020-07-08 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L updated this revision to Diff 276528.
Xiangling_L marked 2 inline comments as done.
Xiangling_L added a comment.

Fixed a -Wpacked related case and added the case to the tests;
Fixed the base class related code issue;
Addressed other comments;


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79719/new/

https://reviews.llvm.org/D79719

Files:
  clang/include/clang/AST/RecordLayout.h
  clang/include/clang/Basic/TargetInfo.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/RecordLayout.cpp
  clang/lib/AST/RecordLayoutBuilder.cpp
  clang/lib/Basic/Targets/OSTargets.h
  clang/lib/Basic/Targets/PPC.h
  clang/test/Layout/aix-Wpacked.cpp
  clang/test/Layout/aix-double-struct-member.cpp
  clang/test/Layout/aix-no-unique-address-with-double.cpp
  clang/test/Layout/aix-pack-attr-on-base.cpp
  clang/test/Layout/aix-power-alignment-typedef.cpp
  clang/test/Layout/aix-virtual-function-and-base-with-double.cpp

Index: clang/test/Layout/aix-virtual-function-and-base-with-double.cpp
===
--- /dev/null
+++ clang/test/Layout/aix-virtual-function-and-base-with-double.cpp
@@ -0,0 +1,112 @@
+// RUN: %clang_cc1 -emit-llvm-only -triple powerpc-ibm-aix-xcoff \
+// RUN: -fdump-record-layouts -fsyntax-only %s | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK32 %s
+
+// RUN: %clang_cc1 -emit-llvm-only -triple powerpc64-ibm-aix-xcoff \
+// RUN: -fdump-record-layouts -fsyntax-only %s | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK64 %s
+
+namespace test1 {
+struct A {
+  double d1;
+  virtual void boo() {}
+};
+
+struct B {
+  double d2;
+  A a;
+};
+
+struct C : public A {
+  double d3;
+};
+
+int i = sizeof(B);
+int j = sizeof(C);
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::A
+// CHECK-NEXT:0 |   (A vtable pointer)
+// CHECK32-NEXT:  4 |   double d1
+// CHECK32-NEXT:| [sizeof=12, dsize=12, align=4, preferredalign=4,
+// CHECK32-NEXT:|  nvsize=12, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:  8 |   double d1
+// CHECK64-NEXT:| [sizeof=16, dsize=16, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=16, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::B
+// CHECK-NEXT:0 |   double d2
+// CHECK-NEXT:8 |   struct test1::A a
+// CHECK-NEXT:8 | (A vtable pointer)
+// CHECK32-NEXT: 12 | double d1
+// CHECK32-NEXT:| [sizeof=24, dsize=20, align=4, preferredalign=8,
+// CHECK32-NEXT:|  nvsize=20, nvalign=4, preferrednvalign=8]
+// CHECK64-NEXT: 16 | double d1
+// CHECK64-NEXT:| [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=24, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::C
+// CHECK-NEXT:0 |   struct test1::A (primary base)
+// CHECK-NEXT:0 | (A vtable pointer)
+// CHECK32-NEXT:  4 | double d1
+// CHECK32-NEXT: 12 |   double d3
+// CHECK32-NEXT:| [sizeof=20, dsize=20, align=4, preferredalign=4,
+// CHECK32-NEXT:|  nvsize=20, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:  8 | double d1
+// CHECK64-NEXT: 16 |   double d3
+// CHECK64-NEXT:| [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=24, nvalign=8, preferrednvalign=8]
+
+} // namespace test1
+
+namespace test2 {
+struct A {
+  long long l1;
+};
+
+struct B : public virtual A {
+  double d2;
+};
+
+#pragma pack(2)
+struct C : public virtual A {
+  double __attribute__((aligned(4))) d3;
+};
+
+int i = sizeof(B);
+int j = sizeof(C);
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::A
+// CHECK-NEXT:0 |   long long l1
+// CHECK-NEXT:  | [sizeof=8, dsize=8, align=8, preferredalign=8,
+// CHECK-NEXT:  |  nvsize=8, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::B
+// CHECK-NEXT:0 |   (B vtable pointer)
+// CHECK32-NEXT:  4 |   double d2
+// CHECK64-NEXT:  8 |   double d2
+// CHECK-NEXT:   16 |   struct test2::A (virtual base)
+// CHECK-NEXT:   16 | long long l1
+// CHECK-NEXT:  | [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK32-NEXT:|  nvsize=12, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:|  nvsize=16, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::C
+// CHECK-NEXT:0 |   (C vtable pointer)
+// CHECK32-NEXT:  4 |   double d3
+// CHECK32-NEXT: 12 |   struct test2::A (virtual base)
+// 

[PATCH] D79719: [AIX] Implement AIX special alignment rule about double/long double

2020-07-08 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L marked an inline comment as done.
Xiangling_L added inline comments.



Comment at: clang/lib/AST/RecordLayoutBuilder.cpp:1796
+  bool FoundFirstNonOverlappingEmptyFieldToHandle =
+  DefaultsToAIXPowerAlignment && FieldOffset == CharUnits::Zero() &&
+  !HandledFirstNonOverlappingEmptyField && !IsOverlappingEmptyField;

hubert.reinterpretcast wrote:
> Xiangling_L wrote:
> > hubert.reinterpretcast wrote:
> > > The condition is still more complex than I think it should be.
> > > 
> > > If we have found a "first" other-than-overlapping-empty-field, then we 
> > > should set `HandledFirstNonOverlappingEmptyField` to `true` for non-union 
> > > cases.
> > > 
> > > If `HandledFirstNonOverlappingEmptyField` being `false` is not enough for 
> > > `FieldOffset == CharUnits::Zero()` to be true, then I think the 
> > > correction would be to set `HandledFirstNonOverlappingEmptyField` in more 
> > > places.
> > > 
> > > I would like to remove the check on `FieldOffset == CharUnits::Zero()` 
> > > from here and instead have an assertion that 
> > > `!HandledFirstNonOverlappingEmptyField` implies `FieldOffset == 
> > > CharUnits::Zero()`.
> > > 
> > > Also, since we're managing `HandledFirstNonOverlappingEmptyField` in 
> > > non-AIX cases, we should remove the `DefaultsToAIXPowerAlignment` 
> > > condition for what is currently named 
> > > `FoundFirstNonOverlappingEmptyFieldToHandle` (adjusting uses of it as 
> > > necessary) and rename `FoundFirstNonOverlappingEmptyFieldToHandle` to 
> > > `FoundFirstNonOverlappingEmptyField`.
> > > Also, since we're managing HandledFirstNonOverlappingEmptyField in 
> > > non-AIX cases, we should remove the DefaultsToAIXPowerAlignment condition 
> > > for what is currently named FoundFirstNonOverlappingEmptyFieldToHandle 
> > 
> > I am not sure if we want to remove the `DefaultsToAIXPowerAlignment` 
> > condition and bother with maintaining correct status of 
> > `HandledFirstNonOverlappingEmptyField` for other targets.
> > 
> > We are actually claiming `HandledFirstNonOverlappingEmptyField` is an 
> > auxiliary flag used for AIX only in its definition comments.
> > 
> > Besides, if we do want to manage `HandledFirstNonOverlappingEmptyField` in 
> > non-AIX cases, I noticed that we have to set this flag to `true` somewhere 
> > for objective-C++ cases. 
> Okay, the other option I'm open is setting 
> `HandledFirstNonOverlappingEmptyField` to `true` up front when not dealing 
> with AIX `power` alignment.
Thanks, that works too. I will address it in the next commit.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79719/new/

https://reviews.llvm.org/D79719



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D79719: [AIX] Implement AIX special alignment rule about double/long double

2020-07-09 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L updated this revision to Diff 276866.
Xiangling_L marked 9 inline comments as done.
Xiangling_L added a comment.

Fixed a base class related case by adding `IsFirstNonEmpty` flag;
Split the `aix-Wpacked.cpp` testcase into two;
Addressed other comments;


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79719/new/

https://reviews.llvm.org/D79719

Files:
  clang/include/clang/AST/RecordLayout.h
  clang/include/clang/Basic/TargetInfo.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/RecordLayout.cpp
  clang/lib/AST/RecordLayoutBuilder.cpp
  clang/lib/Basic/Targets/OSTargets.h
  clang/lib/Basic/Targets/PPC.h
  clang/test/Layout/aix-Wpacked-expecting-diagnostics.cpp
  clang/test/Layout/aix-Wpacked-no-diagnostics.cpp
  clang/test/Layout/aix-double-struct-member.cpp
  clang/test/Layout/aix-no-unique-address-with-double.cpp
  clang/test/Layout/aix-pack-attr-on-base.cpp
  clang/test/Layout/aix-power-alignment-typedef.cpp
  clang/test/Layout/aix-virtual-function-and-base-with-double.cpp

Index: clang/test/Layout/aix-virtual-function-and-base-with-double.cpp
===
--- /dev/null
+++ clang/test/Layout/aix-virtual-function-and-base-with-double.cpp
@@ -0,0 +1,112 @@
+// RUN: %clang_cc1 -emit-llvm-only -triple powerpc-ibm-aix-xcoff \
+// RUN: -fdump-record-layouts -fsyntax-only %s | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK32 %s
+
+// RUN: %clang_cc1 -emit-llvm-only -triple powerpc64-ibm-aix-xcoff \
+// RUN: -fdump-record-layouts -fsyntax-only %s | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK64 %s
+
+namespace test1 {
+struct A {
+  double d1;
+  virtual void boo() {}
+};
+
+struct B {
+  double d2;
+  A a;
+};
+
+struct C : public A {
+  double d3;
+};
+
+int i = sizeof(B);
+int j = sizeof(C);
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::A
+// CHECK-NEXT:0 |   (A vtable pointer)
+// CHECK32-NEXT:  4 |   double d1
+// CHECK32-NEXT:| [sizeof=12, dsize=12, align=4, preferredalign=4,
+// CHECK32-NEXT:|  nvsize=12, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:  8 |   double d1
+// CHECK64-NEXT:| [sizeof=16, dsize=16, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=16, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::B
+// CHECK-NEXT:0 |   double d2
+// CHECK-NEXT:8 |   struct test1::A a
+// CHECK-NEXT:8 | (A vtable pointer)
+// CHECK32-NEXT: 12 | double d1
+// CHECK32-NEXT:| [sizeof=24, dsize=20, align=4, preferredalign=8,
+// CHECK32-NEXT:|  nvsize=20, nvalign=4, preferrednvalign=8]
+// CHECK64-NEXT: 16 | double d1
+// CHECK64-NEXT:| [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=24, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::C
+// CHECK-NEXT:0 |   struct test1::A (primary base)
+// CHECK-NEXT:0 | (A vtable pointer)
+// CHECK32-NEXT:  4 | double d1
+// CHECK32-NEXT: 12 |   double d3
+// CHECK32-NEXT:| [sizeof=20, dsize=20, align=4, preferredalign=4,
+// CHECK32-NEXT:|  nvsize=20, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:  8 | double d1
+// CHECK64-NEXT: 16 |   double d3
+// CHECK64-NEXT:| [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=24, nvalign=8, preferrednvalign=8]
+
+} // namespace test1
+
+namespace test2 {
+struct A {
+  long long l1;
+};
+
+struct B : public virtual A {
+  double d2;
+};
+
+#pragma pack(2)
+struct C : public virtual A {
+  double __attribute__((aligned(4))) d3;
+};
+
+int i = sizeof(B);
+int j = sizeof(C);
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::A
+// CHECK-NEXT:0 |   long long l1
+// CHECK-NEXT:  | [sizeof=8, dsize=8, align=8, preferredalign=8,
+// CHECK-NEXT:  |  nvsize=8, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::B
+// CHECK-NEXT:0 |   (B vtable pointer)
+// CHECK32-NEXT:  4 |   double d2
+// CHECK64-NEXT:  8 |   double d2
+// CHECK-NEXT:   16 |   struct test2::A (virtual base)
+// CHECK-NEXT:   16 | long long l1
+// CHECK-NEXT:  | [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK32-NEXT:|  nvsize=12, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:|  nvsize=16, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::C
+// CHECK-NEXT:0 |   (C vtable pointer)
+// CHECK32-NEXT:  4 

[PATCH] D79719: [AIX] Implement AIX special alignment rule about double/long double

2020-07-10 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L updated this revision to Diff 276991.
Xiangling_L marked 6 inline comments as done.
Xiangling_L added a comment.

Set `Handled...` = true for non-AIX power alignment;
Addressed other comments;


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79719/new/

https://reviews.llvm.org/D79719

Files:
  clang/include/clang/AST/RecordLayout.h
  clang/include/clang/Basic/TargetInfo.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/RecordLayout.cpp
  clang/lib/AST/RecordLayoutBuilder.cpp
  clang/lib/Basic/Targets/OSTargets.h
  clang/lib/Basic/Targets/PPC.h
  clang/test/Layout/aix-Wpacked-expecting-diagnostics.cpp
  clang/test/Layout/aix-Wpacked-no-diagnostics.cpp
  clang/test/Layout/aix-double-struct-member.cpp
  clang/test/Layout/aix-no-unique-address-with-double.cpp
  clang/test/Layout/aix-pack-attr-on-base.cpp
  clang/test/Layout/aix-power-alignment-typedef.cpp
  clang/test/Layout/aix-virtual-function-and-base-with-double.cpp

Index: clang/test/Layout/aix-virtual-function-and-base-with-double.cpp
===
--- /dev/null
+++ clang/test/Layout/aix-virtual-function-and-base-with-double.cpp
@@ -0,0 +1,112 @@
+// RUN: %clang_cc1 -emit-llvm-only -triple powerpc-ibm-aix-xcoff \
+// RUN: -fdump-record-layouts -fsyntax-only %s | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK32 %s
+
+// RUN: %clang_cc1 -emit-llvm-only -triple powerpc64-ibm-aix-xcoff \
+// RUN: -fdump-record-layouts -fsyntax-only %s | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK64 %s
+
+namespace test1 {
+struct A {
+  double d1;
+  virtual void boo() {}
+};
+
+struct B {
+  double d2;
+  A a;
+};
+
+struct C : public A {
+  double d3;
+};
+
+int i = sizeof(B);
+int j = sizeof(C);
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::A
+// CHECK-NEXT:0 |   (A vtable pointer)
+// CHECK32-NEXT:  4 |   double d1
+// CHECK32-NEXT:| [sizeof=12, dsize=12, align=4, preferredalign=4,
+// CHECK32-NEXT:|  nvsize=12, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:  8 |   double d1
+// CHECK64-NEXT:| [sizeof=16, dsize=16, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=16, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::B
+// CHECK-NEXT:0 |   double d2
+// CHECK-NEXT:8 |   struct test1::A a
+// CHECK-NEXT:8 | (A vtable pointer)
+// CHECK32-NEXT: 12 | double d1
+// CHECK32-NEXT:| [sizeof=24, dsize=20, align=4, preferredalign=8,
+// CHECK32-NEXT:|  nvsize=20, nvalign=4, preferrednvalign=8]
+// CHECK64-NEXT: 16 | double d1
+// CHECK64-NEXT:| [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=24, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::C
+// CHECK-NEXT:0 |   struct test1::A (primary base)
+// CHECK-NEXT:0 | (A vtable pointer)
+// CHECK32-NEXT:  4 | double d1
+// CHECK32-NEXT: 12 |   double d3
+// CHECK32-NEXT:| [sizeof=20, dsize=20, align=4, preferredalign=4,
+// CHECK32-NEXT:|  nvsize=20, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:  8 | double d1
+// CHECK64-NEXT: 16 |   double d3
+// CHECK64-NEXT:| [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=24, nvalign=8, preferrednvalign=8]
+
+} // namespace test1
+
+namespace test2 {
+struct A {
+  long long l1;
+};
+
+struct B : public virtual A {
+  double d2;
+};
+
+#pragma pack(2)
+struct C : public virtual A {
+  double __attribute__((aligned(4))) d3;
+};
+
+int i = sizeof(B);
+int j = sizeof(C);
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::A
+// CHECK-NEXT:0 |   long long l1
+// CHECK-NEXT:  | [sizeof=8, dsize=8, align=8, preferredalign=8,
+// CHECK-NEXT:  |  nvsize=8, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::B
+// CHECK-NEXT:0 |   (B vtable pointer)
+// CHECK32-NEXT:  4 |   double d2
+// CHECK64-NEXT:  8 |   double d2
+// CHECK-NEXT:   16 |   struct test2::A (virtual base)
+// CHECK-NEXT:   16 | long long l1
+// CHECK-NEXT:  | [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK32-NEXT:|  nvsize=12, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:|  nvsize=16, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::C
+// CHECK-NEXT:0 |   (C vtable pointer)
+// CHECK32-NEXT:  4 |   double d3
+// CHECK32-NEXT: 12 |   struct test2:

[PATCH] D79719: [AIX] Implement AIX special alignment rule about double/long double

2020-07-13 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L updated this revision to Diff 277417.
Xiangling_L added a comment.

Removed unused var;


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79719/new/

https://reviews.llvm.org/D79719

Files:
  clang/include/clang/AST/RecordLayout.h
  clang/include/clang/Basic/TargetInfo.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/RecordLayout.cpp
  clang/lib/AST/RecordLayoutBuilder.cpp
  clang/lib/Basic/Targets/OSTargets.h
  clang/lib/Basic/Targets/PPC.h
  clang/test/Layout/aix-Wpacked-expecting-diagnostics.cpp
  clang/test/Layout/aix-Wpacked-no-diagnostics.cpp
  clang/test/Layout/aix-double-struct-member.cpp
  clang/test/Layout/aix-no-unique-address-with-double.cpp
  clang/test/Layout/aix-pack-attr-on-base.cpp
  clang/test/Layout/aix-power-alignment-typedef.cpp
  clang/test/Layout/aix-virtual-function-and-base-with-double.cpp

Index: clang/test/Layout/aix-virtual-function-and-base-with-double.cpp
===
--- /dev/null
+++ clang/test/Layout/aix-virtual-function-and-base-with-double.cpp
@@ -0,0 +1,112 @@
+// RUN: %clang_cc1 -emit-llvm-only -triple powerpc-ibm-aix-xcoff \
+// RUN: -fdump-record-layouts -fsyntax-only %s | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK32 %s
+
+// RUN: %clang_cc1 -emit-llvm-only -triple powerpc64-ibm-aix-xcoff \
+// RUN: -fdump-record-layouts -fsyntax-only %s | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK64 %s
+
+namespace test1 {
+struct A {
+  double d1;
+  virtual void boo() {}
+};
+
+struct B {
+  double d2;
+  A a;
+};
+
+struct C : public A {
+  double d3;
+};
+
+int i = sizeof(B);
+int j = sizeof(C);
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::A
+// CHECK-NEXT:0 |   (A vtable pointer)
+// CHECK32-NEXT:  4 |   double d1
+// CHECK32-NEXT:| [sizeof=12, dsize=12, align=4, preferredalign=4,
+// CHECK32-NEXT:|  nvsize=12, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:  8 |   double d1
+// CHECK64-NEXT:| [sizeof=16, dsize=16, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=16, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::B
+// CHECK-NEXT:0 |   double d2
+// CHECK-NEXT:8 |   struct test1::A a
+// CHECK-NEXT:8 | (A vtable pointer)
+// CHECK32-NEXT: 12 | double d1
+// CHECK32-NEXT:| [sizeof=24, dsize=20, align=4, preferredalign=8,
+// CHECK32-NEXT:|  nvsize=20, nvalign=4, preferrednvalign=8]
+// CHECK64-NEXT: 16 | double d1
+// CHECK64-NEXT:| [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=24, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::C
+// CHECK-NEXT:0 |   struct test1::A (primary base)
+// CHECK-NEXT:0 | (A vtable pointer)
+// CHECK32-NEXT:  4 | double d1
+// CHECK32-NEXT: 12 |   double d3
+// CHECK32-NEXT:| [sizeof=20, dsize=20, align=4, preferredalign=4,
+// CHECK32-NEXT:|  nvsize=20, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:  8 | double d1
+// CHECK64-NEXT: 16 |   double d3
+// CHECK64-NEXT:| [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=24, nvalign=8, preferrednvalign=8]
+
+} // namespace test1
+
+namespace test2 {
+struct A {
+  long long l1;
+};
+
+struct B : public virtual A {
+  double d2;
+};
+
+#pragma pack(2)
+struct C : public virtual A {
+  double __attribute__((aligned(4))) d3;
+};
+
+int i = sizeof(B);
+int j = sizeof(C);
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::A
+// CHECK-NEXT:0 |   long long l1
+// CHECK-NEXT:  | [sizeof=8, dsize=8, align=8, preferredalign=8,
+// CHECK-NEXT:  |  nvsize=8, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::B
+// CHECK-NEXT:0 |   (B vtable pointer)
+// CHECK32-NEXT:  4 |   double d2
+// CHECK64-NEXT:  8 |   double d2
+// CHECK-NEXT:   16 |   struct test2::A (virtual base)
+// CHECK-NEXT:   16 | long long l1
+// CHECK-NEXT:  | [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK32-NEXT:|  nvsize=12, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:|  nvsize=16, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::C
+// CHECK-NEXT:0 |   (C vtable pointer)
+// CHECK32-NEXT:  4 |   double d3
+// CHECK32-NEXT: 12 |   struct test2::A (virtual base)
+// CHECK32-NEXT: 12 | long long l1
+// CHECK32-NEXT:| [sizeof=

[PATCH] D79719: [AIX] Implement AIX special alignment rule about double/long double

2020-07-13 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L added inline comments.



Comment at: clang/test/Layout/aix-Wpacked-no-diagnostics.cpp:15
+
+int a = sizeof(QQ);

hubert.reinterpretcast wrote:
> Is there a reason to drop the `FileCheck` checking for the layout?
I dropped the `FileCheck` because the layout of `QQ` and `Q` are fairly simple 
and wanted the test focus more on `no-diagnostics` side. But I can add it back 
if that helps.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79719/new/

https://reviews.llvm.org/D79719



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D83702: [AIX]Generate debug info for static init related functions

2020-07-13 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L created this revision.
Xiangling_L added reviewers: hubert.reinterpretcast, yusra.syeda, jasonliu.
Herald added subscribers: cfe-commits, aprantl.
Herald added a project: clang.

Set the debug location for static init related functions on AIX(__dtor and 
__finalize) so we can generate valid debug info by invoking `-g` with clang or 
`-debug-info-kind=limited` with clang_cc1.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D83702

Files:
  clang/lib/CodeGen/CGDeclCXX.cpp
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/test/CodeGenCXX/aix-static-init-debug-info.cpp

Index: clang/test/CodeGenCXX/aix-static-init-debug-info.cpp
===
--- /dev/null
+++ clang/test/CodeGenCXX/aix-static-init-debug-info.cpp
@@ -0,0 +1,70 @@
+// RUN: %clang_cc1 -triple powerpc-ibm-aix-xcoff -emit-llvm -x c++ \
+// RUN: -debug-info-kind=limited -fno-use-cxa-atexit < %s | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK64 %s
+
+// RUN: %clang_cc1 -triple powerpc64-ibm-aix-xcoff -emit-llvm -x c++ \
+// RUN: -debug-info-kind=limited -fno-use-cxa-atexit < %s | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK64 %s
+
+int a = 0;
+
+class X {
+public:
+  X() {
+a = 1;
+  }
+  ~X() {
+a = -1;
+  }
+};
+
+X v;
+
+// CHECK: define internal void @__cxx_global_var_init() [[ATTR:#[0-9]+]] !dbg ![[DBGVAR19:[0-9]+]] {
+// CHECK: entry:
+// CHECK:   call void @_ZN1XC1Ev(%class.X* @v), !dbg ![[DBGVAR22:[0-9]+]]
+// CHECK:   %0 = call i32 @atexit(void ()* @__dtor_v) [[ATTR:#[0-9]+]], !dbg ![[DBGVAR22]]
+// CHECK:   ret void, !dbg ![[DBGVAR22]]
+// CHECK: }
+
+// CHECK: define internal void @__dtor_v() [[ATTR:#[0-9]+]] !dbg ![[DBGVAR34:[0-9]+]] {
+// CHECK: entry:
+// CHECK:   call void @_ZN1XD1Ev(%class.X* @v), !dbg ![[DBGVAR35:[0-9]+]]
+// CHECK:   ret void, !dbg ![[DBGVAR35]]
+// CHECK: }
+
+// CHECK: define internal void @__finalize_v() [[ATTR:#[0-9]+]] !dbg ![[DBGVAR36:[0-9]+]] {
+// CHECK: entry:
+// CHECK:   %0 = call i32 @unatexit(void ()* @__dtor_v) [[ATTR:#[0-9]+]], !dbg ![[DBGVAR38:[0-9]+]]
+// CHECK:   %needs_destruct = icmp eq i32 %0, 0, !dbg ![[DBGVAR38]]
+// CHECK:   br i1 %needs_destruct, label %destruct.call, label %destruct.end, !dbg ![[DBGVAR38]]
+
+// CHECK: destruct.call:
+// CHECK:   call void @__dtor_v(), !dbg ![[DBGVAR38]]
+// CHECK:   br label %destruct.end, !dbg ![[DBGVAR38]]
+
+// CHECK: destruct.end:
+// CHECK:   ret void, !dbg ![[DBGVAR38]]
+// CHECK: }
+
+// CHECK: define void @__sinit8000_clang_9da80ccf074143d177aee39644eda39d() [[ATTR:#[0-9]+]] !dbg ![[DBGVAR51:[0-9]+]] {
+// CHECK: entry:
+// CHECK:   call void @__cxx_global_var_init(), !dbg ![[DBGVAR52:[0-9]+]]
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define void @__sterm8000_clang_9da80ccf074143d177aee39644eda39d() [[ATTR:#[0-9]+]] !dbg ![[DBGVAR53:[0-9]+]] {
+// CHECK: entry:
+// CHECK:   call void @__finalize_v(), !dbg ![[DBGVAR54:[0-9]+]]
+// CHECK:   ret void
+// CHECK: }
+
+
+// CHECK: ![[DBGVAR19]] = distinct !DISubprogram(name: "__cxx_global_var_init", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: 21, type: !{{[0-9]+}}, scopeLine: 21, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !{{[0-9]+}}, retainedNodes:  !{{[0-9]+}})
+// CHECK: ![[DBGVAR22]] = !DILocation(line: 21, column: 3, scope: ![[DBGVAR19]])
+// CHECK: ![[DBGVAR36]] = distinct !DISubprogram(linkageName: "__finalize_v", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: 21, type: !{{[0-9]+}}, scopeLine: 21, flags: DIFlagArtificial, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !{{[0-9]+}}, retainedNodes: !{{[0-9]+}})
+// CHECK: ![[DBGVAR38]] = !DILocation(line: 21, column: 3, scope: ![[DBGVAR36]])
+// CHECK: ![[DBGVAR51]] = distinct !DISubprogram(linkageName: "__sinit8000_clang_9da80ccf074143d177aee39644eda39d", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, type: !{{[0-9]+}}, flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: !{{[0-9]+}}, retainedNodes: !{{[0-9]+}})
+// CHECK: ![[DBGVAR52]] = !DILocation(line: 0, scope: ![[DBGVAR51]])
+// CHECK: ![[DBGVAR53]] = distinct !DISubprogram(linkageName: "__sterm8000_clang_9da80ccf074143d177aee39644eda39d", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, type: !{{[0-9]+}}, flags: DIFlagArtificial, spFlags: DISPFlagDefinition, unit: !{{[0-9]+}}, retainedNodes: !{{[0-9]+}})
+// CHECK: ![[DBGVAR54]] = !DILocation(line: 0, scope: ![[DBGVAR53]])
Index: clang/lib/CodeGen/ItaniumCXXABI.cpp
===
--- clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -4567,7 +4567,8 @@
   CodeGenFunction CGF(CGM);
 
   CGF.StartFunction(GlobalDecl(), CGM.getContext().VoidTy, StermFinalizer, FI,
-FunctionArgList());
+FunctionArgList(), D.getLocation(),
+D.getInit()->getExprLoc());
 
   // The unatexit subroutine unregisters __dtor functions that were previously
   // registered by the atexit subrou

[PATCH] D83702: [AIX]Generate debug info for static init related functions

2020-07-14 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L updated this revision to Diff 277831.
Xiangling_L marked 6 inline comments as done.
Xiangling_L added a comment.

Simplified the testcase;


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D83702/new/

https://reviews.llvm.org/D83702

Files:
  clang/lib/CodeGen/CGDeclCXX.cpp
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/test/CodeGenCXX/aix-static-init-debug-info.cpp


Index: clang/test/CodeGenCXX/aix-static-init-debug-info.cpp
===
--- /dev/null
+++ clang/test/CodeGenCXX/aix-static-init-debug-info.cpp
@@ -0,0 +1,64 @@
+// RUN: %clang_cc1 -triple powerpc-ibm-aix-xcoff -emit-llvm -x c++ \
+// RUN: -debug-info-kind=limited < %s | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK64 %s
+
+// RUN: %clang_cc1 -triple powerpc64-ibm-aix-xcoff -emit-llvm -x c++ \
+// RUN: -debug-info-kind=limited  < %s | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK64 %s
+
+struct X {
+  X();
+  ~X();
+};
+
+X v;
+
+// CHECK: define internal void @__cxx_global_var_init() [[ATTR:#[0-9]+]] !dbg 
![[DBGVAR16:[0-9]+]] {
+// CHECK: entry:
+// CHECK:   call void @_ZN1XC1Ev(%struct.X* @v), !dbg ![[DBGVAR19:[0-9]+]]
+// CHECK:   %0 = call i32 @atexit(void ()* @__dtor_v) [[ATTR:#[0-9]+]], !dbg 
![[DBGVAR19]]
+// CHECK:   ret void, !dbg ![[DBGVAR19]]
+// CHECK: }
+
+// CHECK: define internal void @__dtor_v() [[ATTR:#[0-9]+]] !dbg 
![[DBGVAR20:[0-9]+]] {
+// CHECK: entry:
+// CHECK:   call void @_ZN1XD1Ev(%struct.X* @v), !dbg ![[DBGVAR21:[0-9]+]]
+// CHECK:   ret void, !dbg ![[DBGVAR21]]
+// CHECK: }
+
+// CHECK: define internal void @__finalize_v() [[ATTR:#[0-9]+]] !dbg 
![[DBGVAR22:[0-9]+]] {
+// CHECK: entry:
+// CHECK:   %0 = call i32 @unatexit(void ()* @__dtor_v) [[ATTR:#[0-9]+]], !dbg 
![[DBGVAR24:[0-9]+]]
+// CHECK:   %needs_destruct = icmp eq i32 %0, 0, !dbg ![[DBGVAR24]]
+// CHECK:   br i1 %needs_destruct, label %destruct.call, label %destruct.end, 
!dbg ![[DBGVAR24]]
+
+// CHECK: destruct.call:
+// CHECK:   call void @__dtor_v(), !dbg ![[DBGVAR24]]
+// CHECK:   br label %destruct.end, !dbg ![[DBGVAR24]]
+
+// CHECK: destruct.end:
+// CHECK:   ret void, !dbg ![[DBGVAR24]]
+// CHECK: }
+
+// CHECK: define void 
@__sinit8000_clang_c3236cbaa79f2bae3a15e6379a05f625() [[ATTR:#[0-9]+]] !dbg 
![[DBGVAR25:[0-9]+]] {
+// CHECK: entry:
+// CHECK:   call void @__cxx_global_var_init(), !dbg ![[DBGVAR26:[0-9]+]]
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define void 
@__sterm8000_clang_c3236cbaa79f2bae3a15e6379a05f625() [[ATTR:#[0-9]+]] !dbg 
![[DBGVAR27:[0-9]+]] {
+// CHECK: entry:
+// CHECK:   call void @__finalize_v(), !dbg ![[DBGVAR28:[0-9]+]]
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: ![[DBGVAR16]] = distinct !DISubprogram(name: 
"__cxx_global_var_init", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: 14, type: 
!{{[0-9]+}}, scopeLine: 14, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, 
unit: !{{[0-9]+}}, retainedNodes: !{{[0-9]+}})
+// CHECK: ![[DBGVAR19]] = !DILocation(line: 14, column: 3, scope: 
![[DBGVAR16]])
+// CHECK: ![[DBGVAR20]] = distinct !DISubprogram(name: "__dtor_v", scope: 
!{{[0-9]+}}, file: !{{[0-9]+}}, line: 14, type: !{{[0-9]+}}, scopeLine: 14, 
spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !{{[0-9]+}}, 
retainedNodes: !{{[0-9]+}})
+// CHECK: ![[DBGVAR21]] = !DILocation(line: 14, column: 3, scope: 
![[DBGVAR20]])
+// CHECK: ![[DBGVAR22]] = distinct !DISubprogram(linkageName: "__finalize_v", 
scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: 14, type: !{{[0-9]+}}, scopeLine: 
14, flags: DIFlagArtificial, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, 
unit: !{{[0-9]+}}, retainedNodes: !{{[0-9]+}})
+// CHECK: ![[DBGVAR24]] = !DILocation(line: 14, column: 3, scope: 
![[DBGVAR22]])
+// CHECK: ![[DBGVAR25]] = distinct !DISubprogram(linkageName: 
"__sinit8000_clang_c3236cbaa79f2bae3a15e6379a05f625", scope: !{{[0-9]+}}, 
file: !{{[0-9]+}}, type: !{{[0-9]+}}, flags: DIFlagArtificial, spFlags: 
DISPFlagDefinition, unit: !{{[0-9]+}}, retainedNodes: !{{[0-9]+}})
+// CHECK: ![[DBGVAR26]] = !DILocation(line: 0, scope: ![[DBGVAR25]])
+// CHECK: ![[DBGVAR27]] = distinct !DISubprogram(linkageName: 
"__sterm8000_clang_c3236cbaa79f2bae3a15e6379a05f625", scope: !{{[0-9]+}}, 
file: !{{[0-9]+}}, type: !{{[0-9]+}}, flags: DIFlagArtificial, spFlags: 
DISPFlagDefinition, unit: !{{[0-9]+}}, retainedNodes: !{{[0-9]+}})
+// CHECK: ![[DBGVAR28]] = !DILocation(line: 0, scope: ![[DBGVAR27]])
Index: clang/lib/CodeGen/ItaniumCXXABI.cpp
===
--- clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -4567,7 +4567,8 @@
   CodeGenFunction CGF(CGM);
 
   CGF.StartFunction(GlobalDecl(), CGM.getContext().VoidTy, StermFinalizer, FI,
-FunctionArgList());
+FunctionArgList(), D.getLocation(),
+D.getInit()->getExprLoc());
 
   // The unatexit subroutine

[PATCH] D74166: [AIX][Frontend] Static init implementation for AIX considering no priority

2020-06-18 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L updated this revision to Diff 271747.
Xiangling_L marked 3 inline comments as done.
Xiangling_L added a comment.

Removed a redundant header file;
Addressed comments;


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D74166/new/

https://reviews.llvm.org/D74166

Files:
  clang/include/clang/AST/Mangle.h
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/CodeGen/CGCXXABI.h
  clang/lib/CodeGen/CGDeclCXX.cpp
  clang/lib/CodeGen/CGOpenMPRuntime.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/CodeGen/CodeGenModule.h
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/lib/CodeGen/MicrosoftCXXABI.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/CodeGen/aix-constructor-attribute.cpp
  clang/test/CodeGen/aix-destructor-attribute.cpp
  clang/test/CodeGen/aix-init-priority-attribute.cpp
  clang/test/CodeGen/static-init.cpp
  clang/test/CodeGenCXX/aix-static-init.cpp

Index: clang/test/CodeGenCXX/aix-static-init.cpp
===
--- /dev/null
+++ clang/test/CodeGenCXX/aix-static-init.cpp
@@ -0,0 +1,193 @@
+// RUN: %clang_cc1 -triple powerpc-ibm-aix-xcoff -S -emit-llvm -x c++ \
+// RUN: -fno-use-cxa-atexit -std=c++2a < %s | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK32 %s
+
+// RUN: %clang_cc1 -triple powerpc64-ibm-aix-xcoff -S -emit-llvm -x c++ \
+// RUN: -fno-use-cxa-atexit -std=c++2a < %s | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK64 %s
+
+namespace test1 {
+  struct Test1 {
+Test1();
+~Test1();
+  } t1, t2;
+} // namespace test1
+
+namespace test2 {
+  int foo() { return 3; }
+  int x = foo();
+} // namespace test2
+
+namespace test3 {
+  struct Test3 {
+constexpr Test3() {};
+~Test3() {};
+  };
+
+  constinit Test3 t;
+} // namespace test3
+
+namespace test4 {
+  struct Test4 {
+Test4();
+~Test4();
+  };
+
+  void f() {
+static Test4 staticLocal;
+  }
+} // namespace test4
+
+// CHECK: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @__sinit8000_clang_1145401da454a7baad10bfe313c46638, i8* null }]
+// CHECK: @llvm.global_dtors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @__sterm8000_clang_1145401da454a7baad10bfe313c46638, i8* null }]
+
+// CHECK: define internal void @__cxx_global_var_init() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   call void @_ZN5test15Test1C1Ev(%"struct.test1::Test1"* @_ZN5test12t1E)
+// CHECK:   %0 = call i32 @atexit(void ()* @__dtor__ZN5test12t1E)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__dtor__ZN5test12t1E() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   call void @_ZN5test15Test1D1Ev(%"struct.test1::Test1"* @_ZN5test12t1E)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: declare i32 @atexit(void ()*)
+
+// CHECK: define internal void @__finalize__ZN5test12t1E() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   %0 = call i32 @unatexit(void ()* @__dtor__ZN5test12t1E)
+// CHECK:   %needs_destruct = icmp eq i32 %0, 0
+// CHECK:   br i1 %needs_destruct, label %destruct.call, label %destruct.end
+
+// CHECK: destruct.call:
+// CHECK:   call void @__dtor__ZN5test12t1E()
+// CHECK:   br label %destruct.end
+
+// CHECK: destruct.end:
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: declare i32 @unatexit(void ()*)
+
+// CHECK: define internal void @__cxx_global_var_init.1() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   call void @_ZN5test15Test1C1Ev(%"struct.test1::Test1"* @_ZN5test12t2E)
+// CHECK:   %0 = call i32 @atexit(void ()* @__dtor__ZN5test12t2E)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__dtor__ZN5test12t2E() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   call void @_ZN5test15Test1D1Ev(%"struct.test1::Test1"* @_ZN5test12t2E)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__finalize__ZN5test12t2E() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   %0 = call i32 @unatexit(void ()* @__dtor__ZN5test12t2E)
+// CHECK:   %needs_destruct = icmp eq i32 %0, 0
+// CHECK:   br i1 %needs_destruct, label %destruct.call, label %destruct.end
+
+// CHECK: destruct.call:
+// CHECK:   call void @__dtor__ZN5test12t2E()
+// CHECK:   br label %destruct.end
+
+// CHECK: destruct.end:
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__cxx_global_var_init.2() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK32: %call = call i32 @_ZN5test23fooEv()
+// CHECK64: %call = call signext i32 @_ZN5test23fooEv()
+// CHECK:   store i32 %call, i32* @_ZN5test21xE
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__cxx_global_var_init.3() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   %0 = call i32 @atexit(void ()* @__dtor__ZN5test31tE)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__dtor__ZN5test31tE() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   call void @_ZN5test35Test3D1Ev(%"struct.te

[PATCH] D74166: [AIX][Frontend] Static init implementation for AIX considering no priority

2020-06-18 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L added inline comments.



Comment at: clang/lib/CodeGen/CGDeclCXX.cpp:345
+// rarely.
+Weights = nullptr;
+  } else if (Kind == GuardKind::VariableGuard && !D->isLocalVarDecl()) {

jasonliu wrote:
> Do we need to change/complicate the interface for this function, just to do a 
> call to Builder.CreateCondBr()?
> Could we call that function directly from where it's needed?
Sure, we can. Thank you for your suggestion. I was hoping to use one function 
to synthesize the guarded init or destruct branch. But I think it seems better 
if we wait for further more usage of guarded destruct branch to do so and not 
complicate stuff in this patch.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D74166/new/

https://reviews.llvm.org/D74166



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D81972: [NFC] Cleanup of EmitCXXGlobalInitFunc() and EmitCXXGlobalDtorFunc()

2020-06-18 Thread Xiangling Liao via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGed1b556954eb: [NFC] Cleanup of EmitCXXGlobalInitFunc() and 
EmitCXXGlobalDtorFunc() (authored by Xiangling_L).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D81972/new/

https://reviews.llvm.org/D81972

Files:
  clang/lib/CodeGen/CGDeclCXX.cpp


Index: clang/lib/CodeGen/CGDeclCXX.cpp
===
--- clang/lib/CodeGen/CGDeclCXX.cpp
+++ clang/lib/CodeGen/CGDeclCXX.cpp
@@ -533,6 +533,22 @@
   CXXThreadLocals.clear();
 }
 
+static SmallString<128> getTransformedFileName(llvm::Module &M) {
+  SmallString<128> FileName = llvm::sys::path::filename(M.getName());
+
+  if (FileName.empty())
+FileName = "";
+
+  for (size_t i = 0; i < FileName.size(); ++i) {
+// Replace everything that's not [a-zA-Z0-9._] with a _. This set happens
+// to be the set of C preprocessing numbers.
+if (!isPreprocessingNumberBody(FileName[i]))
+  FileName[i] = '_';
+  }
+
+  return FileName;
+}
+
 void
 CodeGenModule::EmitCXXGlobalInitFunc() {
   while (!CXXGlobalInits.empty() && !CXXGlobalInits.back())
@@ -577,22 +593,12 @@
 PrioritizedCXXGlobalInits.clear();
   }
 
-  // Include the filename in the symbol name. Including "sub_" matches gcc and
-  // makes sure these symbols appear lexicographically behind the symbols with
-  // priority emitted above.
-  SmallString<128> FileName = llvm::sys::path::filename(getModule().getName());
-  if (FileName.empty())
-FileName = "";
-
-  for (size_t i = 0; i < FileName.size(); ++i) {
-// Replace everything that's not [a-zA-Z0-9._] with a _. This set happens
-// to be the set of C preprocessing numbers.
-if (!isPreprocessingNumberBody(FileName[i]))
-  FileName[i] = '_';
-  }
-
+  // Include the filename in the symbol name. Including "sub_" matches gcc
+  // and makes sure these symbols appear lexicographically behind the symbols
+  // with priority emitted above.
   llvm::Function *Fn = CreateGlobalInitOrDestructFunction(
-  FTy, llvm::Twine("_GLOBAL__sub_I_", FileName), FI);
+  FTy,
+  llvm::Twine("_GLOBAL__sub_I_", getTransformedFileName(getModule())), FI);
 
   CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, CXXGlobalInits);
   AddGlobalCtor(Fn);
@@ -631,6 +637,7 @@
 
   CodeGenFunction(*this).GenerateCXXGlobalDtorsFunc(Fn, CXXGlobalDtors);
   AddGlobalDtor(Fn);
+  CXXGlobalDtors.clear();
 }
 
 /// Emit the code necessary to initialize the given global variable.


Index: clang/lib/CodeGen/CGDeclCXX.cpp
===
--- clang/lib/CodeGen/CGDeclCXX.cpp
+++ clang/lib/CodeGen/CGDeclCXX.cpp
@@ -533,6 +533,22 @@
   CXXThreadLocals.clear();
 }
 
+static SmallString<128> getTransformedFileName(llvm::Module &M) {
+  SmallString<128> FileName = llvm::sys::path::filename(M.getName());
+
+  if (FileName.empty())
+FileName = "";
+
+  for (size_t i = 0; i < FileName.size(); ++i) {
+// Replace everything that's not [a-zA-Z0-9._] with a _. This set happens
+// to be the set of C preprocessing numbers.
+if (!isPreprocessingNumberBody(FileName[i]))
+  FileName[i] = '_';
+  }
+
+  return FileName;
+}
+
 void
 CodeGenModule::EmitCXXGlobalInitFunc() {
   while (!CXXGlobalInits.empty() && !CXXGlobalInits.back())
@@ -577,22 +593,12 @@
 PrioritizedCXXGlobalInits.clear();
   }
 
-  // Include the filename in the symbol name. Including "sub_" matches gcc and
-  // makes sure these symbols appear lexicographically behind the symbols with
-  // priority emitted above.
-  SmallString<128> FileName = llvm::sys::path::filename(getModule().getName());
-  if (FileName.empty())
-FileName = "";
-
-  for (size_t i = 0; i < FileName.size(); ++i) {
-// Replace everything that's not [a-zA-Z0-9._] with a _. This set happens
-// to be the set of C preprocessing numbers.
-if (!isPreprocessingNumberBody(FileName[i]))
-  FileName[i] = '_';
-  }
-
+  // Include the filename in the symbol name. Including "sub_" matches gcc
+  // and makes sure these symbols appear lexicographically behind the symbols
+  // with priority emitted above.
   llvm::Function *Fn = CreateGlobalInitOrDestructFunction(
-  FTy, llvm::Twine("_GLOBAL__sub_I_", FileName), FI);
+  FTy,
+  llvm::Twine("_GLOBAL__sub_I_", getTransformedFileName(getModule())), FI);
 
   CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, CXXGlobalInits);
   AddGlobalCtor(Fn);
@@ -631,6 +637,7 @@
 
   CodeGenFunction(*this).GenerateCXXGlobalDtorsFunc(Fn, CXXGlobalDtors);
   AddGlobalDtor(Fn);
+  CXXGlobalDtors.clear();
 }
 
 /// Emit the code necessary to initialize the given global variable.
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D74166: [AIX][Frontend] Static init implementation for AIX considering no priority

2020-06-19 Thread Xiangling Liao via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Xiangling_L marked an inline comment as done.
Closed by commit rG22337bfe7d87: [AIX][Frontend] Static init implementation for 
AIX considering no priority (authored by Xiangling_L).

Changed prior to commit:
  https://reviews.llvm.org/D74166?vs=271747&id=272035#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D74166/new/

https://reviews.llvm.org/D74166

Files:
  clang/include/clang/AST/Mangle.h
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/CodeGen/CGCXXABI.h
  clang/lib/CodeGen/CGDeclCXX.cpp
  clang/lib/CodeGen/CGOpenMPRuntime.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/CodeGen/CodeGenModule.h
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/lib/CodeGen/MicrosoftCXXABI.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/CodeGen/aix-constructor-attribute.cpp
  clang/test/CodeGen/aix-destructor-attribute.cpp
  clang/test/CodeGen/aix-init-priority-attribute.cpp
  clang/test/CodeGen/static-init.cpp
  clang/test/CodeGenCXX/aix-static-init.cpp

Index: clang/test/CodeGenCXX/aix-static-init.cpp
===
--- /dev/null
+++ clang/test/CodeGenCXX/aix-static-init.cpp
@@ -0,0 +1,193 @@
+// RUN: %clang_cc1 -triple powerpc-ibm-aix-xcoff -S -emit-llvm -x c++ \
+// RUN: -fno-use-cxa-atexit -std=c++2a < %s | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK32 %s
+
+// RUN: %clang_cc1 -triple powerpc64-ibm-aix-xcoff -S -emit-llvm -x c++ \
+// RUN: -fno-use-cxa-atexit -std=c++2a < %s | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK64 %s
+
+namespace test1 {
+  struct Test1 {
+Test1();
+~Test1();
+  } t1, t2;
+} // namespace test1
+
+namespace test2 {
+  int foo() { return 3; }
+  int x = foo();
+} // namespace test2
+
+namespace test3 {
+  struct Test3 {
+constexpr Test3() {};
+~Test3() {};
+  };
+
+  constinit Test3 t;
+} // namespace test3
+
+namespace test4 {
+  struct Test4 {
+Test4();
+~Test4();
+  };
+
+  void f() {
+static Test4 staticLocal;
+  }
+} // namespace test4
+
+// CHECK: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @__sinit8000_clang_1145401da454a7baad10bfe313c46638, i8* null }]
+// CHECK: @llvm.global_dtors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @__sterm8000_clang_1145401da454a7baad10bfe313c46638, i8* null }]
+
+// CHECK: define internal void @__cxx_global_var_init() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   call void @_ZN5test15Test1C1Ev(%"struct.test1::Test1"* @_ZN5test12t1E)
+// CHECK:   %0 = call i32 @atexit(void ()* @__dtor__ZN5test12t1E)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__dtor__ZN5test12t1E() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   call void @_ZN5test15Test1D1Ev(%"struct.test1::Test1"* @_ZN5test12t1E)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: declare i32 @atexit(void ()*)
+
+// CHECK: define internal void @__finalize__ZN5test12t1E() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   %0 = call i32 @unatexit(void ()* @__dtor__ZN5test12t1E)
+// CHECK:   %needs_destruct = icmp eq i32 %0, 0
+// CHECK:   br i1 %needs_destruct, label %destruct.call, label %destruct.end
+
+// CHECK: destruct.call:
+// CHECK:   call void @__dtor__ZN5test12t1E()
+// CHECK:   br label %destruct.end
+
+// CHECK: destruct.end:
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: declare i32 @unatexit(void ()*)
+
+// CHECK: define internal void @__cxx_global_var_init.1() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   call void @_ZN5test15Test1C1Ev(%"struct.test1::Test1"* @_ZN5test12t2E)
+// CHECK:   %0 = call i32 @atexit(void ()* @__dtor__ZN5test12t2E)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__dtor__ZN5test12t2E() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   call void @_ZN5test15Test1D1Ev(%"struct.test1::Test1"* @_ZN5test12t2E)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__finalize__ZN5test12t2E() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   %0 = call i32 @unatexit(void ()* @__dtor__ZN5test12t2E)
+// CHECK:   %needs_destruct = icmp eq i32 %0, 0
+// CHECK:   br i1 %needs_destruct, label %destruct.call, label %destruct.end
+
+// CHECK: destruct.call:
+// CHECK:   call void @__dtor__ZN5test12t2E()
+// CHECK:   br label %destruct.end
+
+// CHECK: destruct.end:
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__cxx_global_var_init.2() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK32: %call = call i32 @_ZN5test23fooEv()
+// CHECK64: %call = call signext i32 @_ZN5test23fooEv()
+// CHECK:   store i32 %call, i32* @_ZN5test21xE
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__cxx_global_var_init.3() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   %0 = call i32 @atexit(void ()* @__dtor

[PATCH] D82136: [AIX] Default AIX to using -fno-use-cxa-atexit

2020-06-19 Thread Xiangling Liao via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Xiangling_L marked 2 inline comments as done.
Closed by commit rG3f2e61c1fe42: [AIX] Default AIX to using -fno-use-cxa-atexit 
(authored by Xiangling_L).
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Changed prior to commit:
  https://reviews.llvm.org/D82136?vs=271885&id=272036#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D82136/new/

https://reviews.llvm.org/D82136

Files:
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/test/CodeGenCXX/aix-static-init.cpp
  clang/test/Driver/cxa-atexit.cpp


Index: clang/test/Driver/cxa-atexit.cpp
===
--- clang/test/Driver/cxa-atexit.cpp
+++ clang/test/Driver/cxa-atexit.cpp
@@ -17,6 +17,8 @@
 // RUN: %clang -### -target mips-unknown-none-gnu -c %s -o /dev/null 2>&1 | 
FileCheck %s -check-prefix CHECK-MIPS
 // RUN: %clang -### -target mips-mti-none-gnu -c %s -o /dev/null 2>&1 | 
FileCheck %s -check-prefix CHECK-MIPS
 // RUN: %clang -### -target sparc-sun-solaris -c %s -o /dev/null 2>&1 | 
FileCheck %s -check-prefix CHECK-SOLARIS
+// RUN: %clang -### -target powerpc-ibm-aix-xcoff -c %s -o /dev/null 2>&1 | 
FileCheck %s -check-prefix CHECK-AIX
+// RUN: %clang -### -target powerpc64-ibm-aix-xcoff -c %s -o /dev/null 2>&1 | 
FileCheck %s -check-prefix CHECK-AIX
 
 // CHECK-WINDOWS: "-fno-use-cxa-atexit"
 // CHECK-SOLARIS-NOT: "-fno-use-cxa-atexit"
@@ -24,6 +26,7 @@
 // CHECK-XCORE: "-fno-use-cxa-atexit"
 // CHECK-MTI: "-fno-use-cxa-atexit"
 // CHECK-MIPS-NOT: "-fno-use-cxa-atexit"
+// CHECK-AIX: "-fno-use-cxa-atexit"
 
 // RUN: %clang -target x86_64-apple-darwin -fregister-global-dtors-with-atexit 
-fno-register-global-dtors-with-atexit -c -### %s 2>&1 | \
 // RUN: FileCheck --check-prefix=WITHOUTATEXIT %s
Index: clang/test/CodeGenCXX/aix-static-init.cpp
===
--- clang/test/CodeGenCXX/aix-static-init.cpp
+++ clang/test/CodeGenCXX/aix-static-init.cpp
@@ -1,9 +1,9 @@
 // RUN: %clang_cc1 -triple powerpc-ibm-aix-xcoff -S -emit-llvm -x c++ \
-// RUN: -fno-use-cxa-atexit -std=c++2a < %s | \
+// RUN: -std=c++2a < %s | \
 // RUN:   FileCheck --check-prefixes=CHECK,CHECK32 %s
 
 // RUN: %clang_cc1 -triple powerpc64-ibm-aix-xcoff -S -emit-llvm -x c++ \
-// RUN: -fno-use-cxa-atexit -std=c++2a < %s | \
+// RUN: -std=c++2a < %s | \
 // RUN:   FileCheck --check-prefixes=CHECK,CHECK64 %s
 
 namespace test1 {
Index: clang/lib/Driver/ToolChains/Clang.cpp
===
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -5498,7 +5498,7 @@
   // -fuse-cxa-atexit is default.
   if (!Args.hasFlag(
   options::OPT_fuse_cxa_atexit, options::OPT_fno_use_cxa_atexit,
-  !RawTriple.isOSWindows() &&
+  !RawTriple.isOSAIX() && !RawTriple.isOSWindows() &&
   TC.getArch() != llvm::Triple::xcore &&
   ((RawTriple.getVendor() != llvm::Triple::MipsTechnologies) ||
RawTriple.hasEnvironment())) ||
Index: clang/lib/CodeGen/ItaniumCXXABI.cpp
===
--- clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -4528,8 +4528,6 @@
   // Create __dtor function for the var decl.
   llvm::Function *dtorStub = CGF.createAtExitStub(D, dtor, addr);
 
-  if (CGM.getCodeGenOpts().CXAAtExit)
-llvm::report_fatal_error("using __cxa_atexit unsupported on AIX");
   // Register above __dtor with atexit().
   CGF.registerGlobalDtorWithAtExit(dtorStub);
 


Index: clang/test/Driver/cxa-atexit.cpp
===
--- clang/test/Driver/cxa-atexit.cpp
+++ clang/test/Driver/cxa-atexit.cpp
@@ -17,6 +17,8 @@
 // RUN: %clang -### -target mips-unknown-none-gnu -c %s -o /dev/null 2>&1 | FileCheck %s -check-prefix CHECK-MIPS
 // RUN: %clang -### -target mips-mti-none-gnu -c %s -o /dev/null 2>&1 | FileCheck %s -check-prefix CHECK-MIPS
 // RUN: %clang -### -target sparc-sun-solaris -c %s -o /dev/null 2>&1 | FileCheck %s -check-prefix CHECK-SOLARIS
+// RUN: %clang -### -target powerpc-ibm-aix-xcoff -c %s -o /dev/null 2>&1 | FileCheck %s -check-prefix CHECK-AIX
+// RUN: %clang -### -target powerpc64-ibm-aix-xcoff -c %s -o /dev/null 2>&1 | FileCheck %s -check-prefix CHECK-AIX
 
 // CHECK-WINDOWS: "-fno-use-cxa-atexit"
 // CHECK-SOLARIS-NOT: "-fno-use-cxa-atexit"
@@ -24,6 +26,7 @@
 // CHECK-XCORE: "-fno-use-cxa-atexit"
 // CHECK-MTI: "-fno-use-cxa-atexit"
 // CHECK-MIPS-NOT: "-fno-use-cxa-atexit"
+// CHECK-AIX: "-fno-use-cxa-atexit"
 
 // RUN: %clang -target x86_64-apple-darwin -fregister-global-dtors-with-atexit -fno-register-global-dtors-with-atexit -c -### %s 2>&1 | \
 // RUN: FileCheck --check-prefix=WITHOUTATEXIT %s
Index: clang/tes

[PATCH] D79719: [AIX] Implement AIX special alignment rule about double/long double

2020-06-23 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L added inline comments.



Comment at: clang/lib/AST/ASTContext.cpp:2424
+  (T->isSpecificBuiltinType(BuiltinType::LongDouble) &&
+   Target->supportsAIXPowerAlignment()))
 // Don't increase the alignment if an alignment attribute was specified on 
a

hubert.reinterpretcast wrote:
> Does `supportsAIXPowerAlignment` express the condition we want to check here? 
> That might be true for an implementation operating with `mac68k` alignment 
> rules.
Yeah, `supportsAIXPowerAlignment` cannot separate the preferred alignment of 
double, long double between `power/natural` and `mac68k` alignment rules. But I 
noticed that currently, AIX target on wyvern or XL don't support `mac68k` , so 
maybe we should leave further changes to the patch which is gonna implement 
`mac68k` alignment rules? The possible solution I am thinking is we can add 
checking if the decl has `AlignMac68kAttr` into query to separate things out.

Another thing is that once we start supporting mac68k alignment rule(if we 
will), should we also change the ABI align values as well? (e.g. for double, it 
should be 2 instead)



Comment at: clang/lib/AST/RecordLayoutBuilder.cpp:660
+  /// When there are OverlappingEmptyFields existing in the aggregate, the
+  /// flag shows if the following first non-overlappingEmptyField has been
+  /// handled, if any.

hubert.reinterpretcast wrote:
> I suggest to replace (if correct) "non-overlappingEmptyField" with "non-empty 
> or empty-but-non-overlapping field".
> 
Thanks for your suggestion. But I kinda prefer using 
`NonOverlappingEmptyField`, it is more consistent with 
`IsOverlappingEmptyField`. And also the equivalent name to 
`NonOverlappingEmptyField` is `NonOverlappingAndNonEmptyField` which is tedious 
I think.



Comment at: clang/lib/AST/RecordLayoutBuilder.cpp:1881
+  if (isAIXLayout(Context) && FieldOffset == CharUnits::Zero() &&
+  (IsUnion || NonOverlappingEmptyFieldFound)) {
+FirstNonOverlappingEmptyFieldHandled = true;

jasonliu wrote:
> Maybe it's a naive thought, but is it possible to replace 
> `NonOverlappingEmptyFieldFound` with `IsOverlappingEmptyField && 
> FieldOffsets.size() == 0`?
I don't think these two work the same. `NonOverlappingEmptyFieldFound` 
represents the 1st non-empty and non-overlapping field in the record. 
`IsOverlappingEmptyField && FieldOffsets.size() == 0` represents something 
opposite.



Comment at: clang/lib/AST/RecordLayoutBuilder.cpp:1943
 getDataSize() != CharUnits::Zero())
   FieldOffset = getDataSize().alignTo(FieldAlign);
 else

jasonliu wrote:
> hmm... Are we sure we should use FieldAlign instead of PreferredAlign here?
> Same for the else below.
The way I see the `PreferredAlign` is not the `real alignment` the record uses 
(which I believe the community don't expect us to see it that way either). All 
code here should be attached to `ABI align`. Specially, on AIX, 
`PreferredAlign` is something we use to round up the record size, but it won't 
affect the record layout besides of that. So in other words, we are just 
tracking what `PreferredAlignment` value is here.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79719/new/

https://reviews.llvm.org/D79719



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D79719: [AIX] Implement AIX special alignment rule about double/long double

2020-06-23 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L updated this revision to Diff 272741.
Xiangling_L marked 24 inline comments as done.
Xiangling_L added a comment.

Addressed comments;
Fixed the ICE problem with array as first member;
Add support for Complex type;


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79719/new/

https://reviews.llvm.org/D79719

Files:
  clang/include/clang/AST/RecordLayout.h
  clang/include/clang/Basic/TargetInfo.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/RecordLayout.cpp
  clang/lib/AST/RecordLayoutBuilder.cpp
  clang/lib/Basic/Targets/OSTargets.h
  clang/lib/Basic/Targets/PPC.h
  clang/test/Layout/aix-double-struct-member.cpp
  clang/test/Layout/aix-no-unique-address-with-double.cpp
  clang/test/Layout/aix-virtual-function-and-base-with-double.cpp

Index: clang/test/Layout/aix-virtual-function-and-base-with-double.cpp
===
--- /dev/null
+++ clang/test/Layout/aix-virtual-function-and-base-with-double.cpp
@@ -0,0 +1,112 @@
+// RUN: %clang_cc1 -emit-llvm-only -triple powerpc-ibm-aix-xcoff \
+// RUN: -fdump-record-layouts -fsyntax-only %s 2>/dev/null | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK32 %s
+
+// RUN: %clang_cc1 -emit-llvm-only -triple powerpc64-ibm-aix-xcoff \
+// RUN: -fdump-record-layouts -fsyntax-only %s 2>/dev/null | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK64 %s
+
+namespace test1 {
+struct A {
+  double d1;
+  virtual void boo() {}
+};
+
+struct B {
+  double d2;
+  A a;
+};
+
+struct C : public A {
+  double d3;
+};
+
+int i = sizeof(B);
+int j = sizeof(C);
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::A
+// CHECK-NEXT:0 |   (A vtable pointer)
+// CHECK32-NEXT:  4 |   double d1
+// CHECK32-NEXT:| [sizeof=12, dsize=12, align=4, preferredalign=4,
+// CHECK32-NEXT:|  nvsize=12, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:  8 |   double d1
+// CHECK64-NEXT:| [sizeof=16, dsize=16, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=16, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::B
+// CHECK-NEXT:0 |   double d2
+// CHECK-NEXT:8 |   struct test1::A a
+// CHECK-NEXT:8 | (A vtable pointer)
+// CHECK32-NEXT: 12 | double d1
+// CHECK32-NEXT:| [sizeof=24, dsize=20, align=4, preferredalign=8,
+// CHECK32-NEXT:|  nvsize=20, nvalign=4, preferrednvalign=8]
+// CHECK64-NEXT: 16 | double d1
+// CHECK64-NEXT:| [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=24, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::C
+// CHECK-NEXT:0 |   struct test1::A (primary base)
+// CHECK-NEXT:0 | (A vtable pointer)
+// CHECK32-NEXT:  4 | double d1
+// CHECK32-NEXT: 12 |   double d3
+// CHECK32-NEXT:| [sizeof=20, dsize=20, align=4, preferredalign=4,
+// CHECK32-NEXT:|  nvsize=20, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:  8 | double d1
+// CHECK64-NEXT: 16 |   double d3
+// CHECK64-NEXT:| [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=24, nvalign=8, preferrednvalign=8]
+
+} // namespace test1
+
+namespace test2 {
+struct A {
+  long long l1;
+};
+
+struct B : public virtual A {
+  double d2;
+};
+
+#pragma pack(2)
+struct C : public virtual A {
+  double __attribute__((aligned(4))) d3;
+};
+
+int i = sizeof(B);
+int j = sizeof(C);
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::A
+// CHECK-NEXT:0 |   long long l1
+// CHECK-NEXT:  | [sizeof=8, dsize=8, align=8, preferredalign=8,
+// CHECK-NEXT:  |  nvsize=8, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::B
+// CHECK-NEXT:0 |   (B vtable pointer)
+// CHECK32-NEXT:  4 |   double d2
+// CHECK64-NEXT:  8 |   double d2
+// CHECK-NEXT:   16 |   struct test2::A (virtual base)
+// CHECK-NEXT:   16 | long long l1
+// CHECK-NEXT:  | [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK32-NEXT:|  nvsize=12, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:|  nvsize=16, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::C
+// CHECK-NEXT:0 |   (C vtable pointer)
+// CHECK32-NEXT:  4 |   double d3
+// CHECK32-NEXT: 12 |   struct test2::A (virtual base)
+// CHECK32-NEXT: 12 | long long l1
+// CHECK32-NEXT:| [sizeof=20, dsize=20, align=2, preferredalign=2,
+// CHECK32-NEX

[PATCH] D79719: [AIX] Implement AIX special alignment rule about double/long double

2020-06-23 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L updated this revision to Diff 272824.
Xiangling_L marked 2 inline comments as done.
Xiangling_L added a comment.

Adjust the function name;
Adjust the comment;


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79719/new/

https://reviews.llvm.org/D79719

Files:
  clang/include/clang/AST/RecordLayout.h
  clang/include/clang/Basic/TargetInfo.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/RecordLayout.cpp
  clang/lib/AST/RecordLayoutBuilder.cpp
  clang/lib/Basic/Targets/OSTargets.h
  clang/lib/Basic/Targets/PPC.h
  clang/test/Layout/aix-double-struct-member.cpp
  clang/test/Layout/aix-no-unique-address-with-double.cpp
  clang/test/Layout/aix-virtual-function-and-base-with-double.cpp

Index: clang/test/Layout/aix-virtual-function-and-base-with-double.cpp
===
--- /dev/null
+++ clang/test/Layout/aix-virtual-function-and-base-with-double.cpp
@@ -0,0 +1,112 @@
+// RUN: %clang_cc1 -emit-llvm-only -triple powerpc-ibm-aix-xcoff \
+// RUN: -fdump-record-layouts -fsyntax-only %s 2>/dev/null | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK32 %s
+
+// RUN: %clang_cc1 -emit-llvm-only -triple powerpc64-ibm-aix-xcoff \
+// RUN: -fdump-record-layouts -fsyntax-only %s 2>/dev/null | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK64 %s
+
+namespace test1 {
+struct A {
+  double d1;
+  virtual void boo() {}
+};
+
+struct B {
+  double d2;
+  A a;
+};
+
+struct C : public A {
+  double d3;
+};
+
+int i = sizeof(B);
+int j = sizeof(C);
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::A
+// CHECK-NEXT:0 |   (A vtable pointer)
+// CHECK32-NEXT:  4 |   double d1
+// CHECK32-NEXT:| [sizeof=12, dsize=12, align=4, preferredalign=4,
+// CHECK32-NEXT:|  nvsize=12, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:  8 |   double d1
+// CHECK64-NEXT:| [sizeof=16, dsize=16, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=16, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::B
+// CHECK-NEXT:0 |   double d2
+// CHECK-NEXT:8 |   struct test1::A a
+// CHECK-NEXT:8 | (A vtable pointer)
+// CHECK32-NEXT: 12 | double d1
+// CHECK32-NEXT:| [sizeof=24, dsize=20, align=4, preferredalign=8,
+// CHECK32-NEXT:|  nvsize=20, nvalign=4, preferrednvalign=8]
+// CHECK64-NEXT: 16 | double d1
+// CHECK64-NEXT:| [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=24, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::C
+// CHECK-NEXT:0 |   struct test1::A (primary base)
+// CHECK-NEXT:0 | (A vtable pointer)
+// CHECK32-NEXT:  4 | double d1
+// CHECK32-NEXT: 12 |   double d3
+// CHECK32-NEXT:| [sizeof=20, dsize=20, align=4, preferredalign=4,
+// CHECK32-NEXT:|  nvsize=20, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:  8 | double d1
+// CHECK64-NEXT: 16 |   double d3
+// CHECK64-NEXT:| [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=24, nvalign=8, preferrednvalign=8]
+
+} // namespace test1
+
+namespace test2 {
+struct A {
+  long long l1;
+};
+
+struct B : public virtual A {
+  double d2;
+};
+
+#pragma pack(2)
+struct C : public virtual A {
+  double __attribute__((aligned(4))) d3;
+};
+
+int i = sizeof(B);
+int j = sizeof(C);
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::A
+// CHECK-NEXT:0 |   long long l1
+// CHECK-NEXT:  | [sizeof=8, dsize=8, align=8, preferredalign=8,
+// CHECK-NEXT:  |  nvsize=8, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::B
+// CHECK-NEXT:0 |   (B vtable pointer)
+// CHECK32-NEXT:  4 |   double d2
+// CHECK64-NEXT:  8 |   double d2
+// CHECK-NEXT:   16 |   struct test2::A (virtual base)
+// CHECK-NEXT:   16 | long long l1
+// CHECK-NEXT:  | [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK32-NEXT:|  nvsize=12, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:|  nvsize=16, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::C
+// CHECK-NEXT:0 |   (C vtable pointer)
+// CHECK32-NEXT:  4 |   double d3
+// CHECK32-NEXT: 12 |   struct test2::A (virtual base)
+// CHECK32-NEXT: 12 | long long l1
+// CHECK32-NEXT:| [sizeof=20, dsize=20, align=2, preferredalign=2,
+// CHECK32-NEXT:|  nvsize=12, nvalign=2, preferrednvalign

[PATCH] D79719: [AIX] Implement AIX special alignment rule about double/long double

2020-06-24 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L marked 2 inline comments as done.
Xiangling_L added inline comments.



Comment at: clang/lib/AST/RecordLayoutBuilder.cpp:1881
+  if (isAIXLayout(Context) && FieldOffset == CharUnits::Zero() &&
+  (IsUnion || NonOverlappingEmptyFieldFound)) {
+FirstNonOverlappingEmptyFieldHandled = true;

jasonliu wrote:
> Xiangling_L wrote:
> > jasonliu wrote:
> > > Maybe it's a naive thought, but is it possible to replace 
> > > `NonOverlappingEmptyFieldFound` with `IsOverlappingEmptyField && 
> > > FieldOffsets.size() == 0`?
> > I don't think these two work the same. `NonOverlappingEmptyFieldFound` 
> > represents the 1st non-empty and non-overlapping field in the record. 
> > `IsOverlappingEmptyField && FieldOffsets.size() == 0` represents something 
> > opposite.
> You are right. I meant could we replace it with `!(IsOverlappingEmptyField && 
> FieldOffsets.size() == 0)`?
I don't think so. The replacement does not work for the case:


```
struct A {
  int : 0;
  double d;
};
```

where __alignof(A) should be 4;


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79719/new/

https://reviews.llvm.org/D79719



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D79719: [AIX] Implement AIX special alignment rule about double/long double

2020-06-26 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L updated this revision to Diff 273708.
Xiangling_L marked 2 inline comments as done.
Xiangling_L added a comment.

Corrected the comments;


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79719/new/

https://reviews.llvm.org/D79719

Files:
  clang/include/clang/AST/RecordLayout.h
  clang/include/clang/Basic/TargetInfo.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/RecordLayout.cpp
  clang/lib/AST/RecordLayoutBuilder.cpp
  clang/lib/Basic/Targets/OSTargets.h
  clang/lib/Basic/Targets/PPC.h
  clang/test/Layout/aix-double-struct-member.cpp
  clang/test/Layout/aix-no-unique-address-with-double.cpp
  clang/test/Layout/aix-virtual-function-and-base-with-double.cpp

Index: clang/test/Layout/aix-virtual-function-and-base-with-double.cpp
===
--- /dev/null
+++ clang/test/Layout/aix-virtual-function-and-base-with-double.cpp
@@ -0,0 +1,112 @@
+// RUN: %clang_cc1 -emit-llvm-only -triple powerpc-ibm-aix-xcoff \
+// RUN: -fdump-record-layouts -fsyntax-only %s 2>/dev/null | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK32 %s
+
+// RUN: %clang_cc1 -emit-llvm-only -triple powerpc64-ibm-aix-xcoff \
+// RUN: -fdump-record-layouts -fsyntax-only %s 2>/dev/null | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK64 %s
+
+namespace test1 {
+struct A {
+  double d1;
+  virtual void boo() {}
+};
+
+struct B {
+  double d2;
+  A a;
+};
+
+struct C : public A {
+  double d3;
+};
+
+int i = sizeof(B);
+int j = sizeof(C);
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::A
+// CHECK-NEXT:0 |   (A vtable pointer)
+// CHECK32-NEXT:  4 |   double d1
+// CHECK32-NEXT:| [sizeof=12, dsize=12, align=4, preferredalign=4,
+// CHECK32-NEXT:|  nvsize=12, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:  8 |   double d1
+// CHECK64-NEXT:| [sizeof=16, dsize=16, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=16, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::B
+// CHECK-NEXT:0 |   double d2
+// CHECK-NEXT:8 |   struct test1::A a
+// CHECK-NEXT:8 | (A vtable pointer)
+// CHECK32-NEXT: 12 | double d1
+// CHECK32-NEXT:| [sizeof=24, dsize=20, align=4, preferredalign=8,
+// CHECK32-NEXT:|  nvsize=20, nvalign=4, preferrednvalign=8]
+// CHECK64-NEXT: 16 | double d1
+// CHECK64-NEXT:| [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=24, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::C
+// CHECK-NEXT:0 |   struct test1::A (primary base)
+// CHECK-NEXT:0 | (A vtable pointer)
+// CHECK32-NEXT:  4 | double d1
+// CHECK32-NEXT: 12 |   double d3
+// CHECK32-NEXT:| [sizeof=20, dsize=20, align=4, preferredalign=4,
+// CHECK32-NEXT:|  nvsize=20, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:  8 | double d1
+// CHECK64-NEXT: 16 |   double d3
+// CHECK64-NEXT:| [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK64-NEXT:|  nvsize=24, nvalign=8, preferrednvalign=8]
+
+} // namespace test1
+
+namespace test2 {
+struct A {
+  long long l1;
+};
+
+struct B : public virtual A {
+  double d2;
+};
+
+#pragma pack(2)
+struct C : public virtual A {
+  double __attribute__((aligned(4))) d3;
+};
+
+int i = sizeof(B);
+int j = sizeof(C);
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::A
+// CHECK-NEXT:0 |   long long l1
+// CHECK-NEXT:  | [sizeof=8, dsize=8, align=8, preferredalign=8,
+// CHECK-NEXT:  |  nvsize=8, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::B
+// CHECK-NEXT:0 |   (B vtable pointer)
+// CHECK32-NEXT:  4 |   double d2
+// CHECK64-NEXT:  8 |   double d2
+// CHECK-NEXT:   16 |   struct test2::A (virtual base)
+// CHECK-NEXT:   16 | long long l1
+// CHECK-NEXT:  | [sizeof=24, dsize=24, align=8, preferredalign=8,
+// CHECK32-NEXT:|  nvsize=12, nvalign=4, preferrednvalign=4]
+// CHECK64-NEXT:|  nvsize=16, nvalign=8, preferrednvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::C
+// CHECK-NEXT:0 |   (C vtable pointer)
+// CHECK32-NEXT:  4 |   double d3
+// CHECK32-NEXT: 12 |   struct test2::A (virtual base)
+// CHECK32-NEXT: 12 | long long l1
+// CHECK32-NEXT:| [sizeof=20, dsize=20, align=2, preferredalign=2,
+// CHECK32-NEXT:|  nvsize=12, nvalign=2,

[PATCH] D82806: [AIX] Static init support for template specialization and inline variable

2020-06-29 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L created this revision.
Xiangling_L added reviewers: hubert.reinterpretcast, jasonliu, yusra.syeda, 
ZarkoCA, sfertile.
Herald added subscribers: cfe-commits, jfb.
Herald added a project: clang.

This is a follow-up patch of D74166 .

This patch adds static init support for template specialization kinds that were 
left out by D74166  [implicit instantiation, 
explicit instantiation definition] and inline variable.

Also.it adds a test for explicit specialization TSK.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D82806

Files:
  clang/lib/CodeGen/CGDeclCXX.cpp
  clang/test/CodeGenCXX/aix-static-init-temp-spec-and-inline-var.cpp

Index: clang/test/CodeGenCXX/aix-static-init-temp-spec-and-inline-var.cpp
===
--- /dev/null
+++ clang/test/CodeGenCXX/aix-static-init-temp-spec-and-inline-var.cpp
@@ -0,0 +1,238 @@
+// RUN: %clang_cc1 -triple powerpc-ibm-aix-xcoff -S -emit-llvm -x c++ \
+// RUN: -std=c++2a < %s | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK32 %s
+
+// RUN: %clang_cc1 -triple powerpc64-ibm-aix-xcoff -S -emit-llvm -x c++ \
+// RUN: -std=c++2a < %s | \
+// RUN:   FileCheck --check-prefixes=CHECK,CHECK64 %s
+
+namespace test1 {
+  struct Test1 {
+Test1(int) {}
+~Test1() {}
+  };
+
+  Test1 t0 = 2;
+  template  Test1 t1 = 2;
+  inline Test1 t2 = 2;
+
+  void foo() {
+(void) &t1;
+  }
+} // namespace test1
+
+namespace test2 {
+  template 
+  struct A {
+A() {}
+~A() {}
+static A instance;
+  };
+
+  template  A A::instance;
+  template A<> A<>::instance;
+
+  A &bar() { 
+A *a = new A;
+return *a;
+  }
+  template<> A A::instance = bar();
+} // namespace test2
+
+// CHECK: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @__sinit8000_clang_32add9385a76444cd9d0fab0fb83307b, i8* null }]
+// CHECK: @llvm.global_dtors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @__sterm8000_clang_32add9385a76444cd9d0fab0fb83307b, i8* null }]
+
+// CHECK: define internal void @__cxx_global_var_init() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK32: call void @_ZN5test15Test1C1Ei(%"struct.test1::Test1"* @_ZN5test12t0E, i32 2)
+// CHECK64: call void @_ZN5test15Test1C1Ei(%"struct.test1::Test1"* @_ZN5test12t0E, i32 signext 2)
+// CHECK:   %0 = call i32 @atexit(void ()* @__dtor__ZN5test12t0E)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__dtor__ZN5test12t0E() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   call void @_ZN5test15Test1D1Ev(%"struct.test1::Test1"* @_ZN5test12t0E)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: declare i32 @atexit(void ()*)
+
+// CHECK: define internal void @__finalize__ZN5test12t0E() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   %0 = call i32 @unatexit(void ()* @__dtor__ZN5test12t0E)
+// CHECK:   %needs_destruct = icmp eq i32 %0, 0
+// CHECK:   br i1 %needs_destruct, label %destruct.call, label %destruct.end
+
+// CHECK: destruct.call:
+// CHECK:   call void @__dtor__ZN5test12t0E()
+// CHECK:   br label %destruct.end
+
+// CHECK: destruct.end:
+ //CHECK:   ret void
+// CHECK: }
+
+// CHECK: declare i32 @unatexit(void ()*)
+
+// CHECK: define internal void @__cxx_global_var_init.1() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   %0 = load atomic i8, i8* bitcast (i64* @_ZGVN5test12t2E to i8*) acquire
+// CHECK:   %guard.uninitialized = icmp eq i8 %0, 0
+// CHECK:   br i1 %guard.uninitialized, label %init.check, label %init.end
+
+// CHECK: init.check:
+ //CHECK:   %1 = call i32 @__cxa_guard_acquire(i64* @_ZGVN5test12t2E)
+// CHECK:   %tobool = icmp ne i32 %1, 0
+// CHECK:   br i1 %tobool, label %init, label %init.end
+
+// CHECK: init:
+// CHECK32: call void @_ZN5test15Test1C1Ei(%"struct.test1::Test1"* @_ZN5test12t2E, i32 2)
+// CHECK64: call void @_ZN5test15Test1C1Ei(%"struct.test1::Test1"* @_ZN5test12t2E, i32 signext 2)
+// CHECK:   %2 = call i32 @atexit(void ()* @__dtor__ZN5test12t2E)
+// CHECK:   call void @__cxa_guard_release(i64* @_ZGVN5test12t2E)
+// CHECK:   br label %init.end
+
+// CHECK: init.end:
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__dtor__ZN5test12t2E() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   call void @_ZN5test15Test1D1Ev(%"struct.test1::Test1"* @_ZN5test12t2E)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void @__finalize__ZN5test12t2E() [[ATTR:#[0-9]+]] {
+// CHECK: entry:
+// CHECK:   %0 = call i32 @unatexit(void ()* @__dtor__ZN5test12t2E)
+// CHECK:   %needs_destruct = icmp eq i32 %0, 0
+// CHECK:   br i1 %needs_destruct, label %destruct.call, label %destruct.end
+
+// CHECK: destruct.call:
+// CHECK:   call void @__dtor__ZN5test12t2E()
+// CHECK:   br label %destruct.end
+
+// CHECK: destruct.end:
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define internal void 

[PATCH] D82806: [AIX] Static init support for template specialization and inline variable

2020-06-30 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L abandoned this revision.
Xiangling_L added a comment.

Abandon this revision to keep separable C++ initialization  as it is and will 
handle them in the backend later.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D82806/new/

https://reviews.llvm.org/D82806



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D78563: [AIX] Port power alignment rules to clang

2020-04-21 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L created this revision.
Xiangling_L added reviewers: jasonliu, hubert.reinterpretcast, sfertile.
Xiangling_L added a project: LLVM.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Address the following aspects of power alignment rules:

- Implemented double/long double alignment when not first struct member
- A double member in union is always treated as the first member, and should 
not use special alignment rule
- Fixed the alignment issue caused by virtual function
- Applied AIX Alignment rule when layout base class
- Fixed AIX layout for zero sized bitfield followed by double


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D78563

Files:
  clang/include/clang/AST/RecordLayout.h
  clang/lib/AST/RecordLayout.cpp
  clang/lib/AST/RecordLayoutBuilder.cpp
  clang/test/Layout/aix-double-struct-member.cpp
  clang/test/Layout/aix-virtual-function-alignment.cpp

Index: clang/test/Layout/aix-virtual-function-alignment.cpp
===
--- /dev/null
+++ clang/test/Layout/aix-virtual-function-alignment.cpp
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -emit-llvm-only -triple powerpc-ibm-aix-xcoff \
+// RUN: -fdump-record-layouts -fsyntax-only %s 2>/dev/null | FileCheck \
+// RUN: --check-prefix=CHECK32 %s
+
+// RUN: %clang_cc1 -emit-llvm-only -triple powerpc64-ibm-aix-xcoff \
+// RUN: -fdump-record-layouts -fsyntax-only %s 2>/dev/null | FileCheck \
+// RUN: --check-prefix=CHECK64 %s
+
+struct A {
+  virtual void boo() {}
+};
+
+struct B {
+  bool b;
+  A a;
+};
+
+int i = sizeof(B);
+
+// CHECK32:  *** Dumping AST Record Layout
+// CHECK32-NEXT:  0 | struct A
+// CHECK32-NEXT:  0 |   (A vtable pointer)
+// CHECK32-NEXT:| [sizeof=4, dsize=4, align=4,
+// CHECK32-NEXT:|  nvsize=4, nvalign=4]
+
+// CHECK32:  *** Dumping AST Record Layout
+// CHECK32-NEXT:  0 | struct B
+// CHECK32-NEXT:  0 |   _Bool b
+// CHECK32-NEXT:  4 |   struct A a
+// CHECK32-NEXT:  4 | (A vtable pointer)
+// CHECK32-NEXT:| [sizeof=8, dsize=8, align=4,
+// CHECK32-NEXT:|  nvsize=8, nvalign=4]
+
+// CHECK64:  *** Dumping AST Record Layout
+// CHECK64-NEXT:  0 | struct A
+// CHECK64-NEXT:  0 |   (A vtable pointer)
+// CHECK64-NEXT:| [sizeof=8, dsize=8, align=8,
+// CHECK64-NEXT:|  nvsize=8, nvalign=8]
+
+// CHECK64:  *** Dumping AST Record Layout
+// CHECK64-NEXT:  0 | struct B
+// CHECK64-NEXT:  0 |   _Bool b
+// CHECK64-NEXT:  8 |   struct A a
+// CHECK64-NEXT:  8 | (A vtable pointer)
+// CHECK64-NEXT:| [sizeof=16, dsize=16, align=8,
+// CHECK64-NEXT:|  nvsize=16, nvalign=8]
Index: clang/test/Layout/aix-double-struct-member.cpp
===
--- /dev/null
+++ clang/test/Layout/aix-double-struct-member.cpp
@@ -0,0 +1,136 @@
+// RUN: %clang_cc1 -emit-llvm-only -triple powerpc-ibm-aix-xcoff \
+// RUN: -fdump-record-layouts -fsyntax-only %s 2>/dev/null | FileCheck %s
+
+// RUN: %clang_cc1 -emit-llvm-only -triple powerpc64-ibm-aix-xcoff \
+// RUN: -fdump-record-layouts -fsyntax-only %s 2>/dev/null | FileCheck %s
+
+namespace test1 {
+// Test double alignment when it is/is not the first struct member.
+struct D {
+  double d1;
+  int i1;
+};
+
+struct DoubleFirst {
+  struct D d2;
+  int i2;
+};
+
+struct IntFirst {
+  int i3;
+  struct D d3;
+};
+
+int a = sizeof(DoubleFirst);
+int b = sizeof(IntFirst);
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT: 0 | struct test1::D
+// CHECK-NEXT: 0 |   double d1
+// CHECK-NEXT: 8 |   int i1
+// CHECK-NEXT:   | [sizeof=16, dsize=16, align=8,
+// CHECK-NEXT:   |  nvsize=16, nvalign=8]
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT: 0 | struct test1::DoubleFirst
+// CHECK-NEXT: 0 |   struct test1::D d2
+// CHECK-NEXT: 0 | double d1
+// CHECK-NEXT: 8 | int i1
+// CHECK-NEXT:16 |   int i2
+// CHECK-NEXT:   | [sizeof=24, dsize=24, align=8,
+// CHECK-NEXT:   |  nvsize=24, nvalign=8]
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT: 0 | struct test1::IntFirst
+// CHECK-NEXT: 0 |   int i3
+// CHECK-NEXT: 4 |   struct test1::D d3
+// CHECK-NEXT: 4 | double d1
+// CHECK-NEXT:12 | int i1
+// CHECK-NEXT:   | [sizeof=20, dsize=20, align=4,
+// CHECK-NEXT:   |  nvsize=20, nvalign=4]
+}; // namespace test1
+
+namespace test2 {
+// Test AIX layout for zero sized bitfield followed by double.
+struct Double {
+  int : 0;
+  double d;
+};
+
+int a = sizeof(Double);
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT: 0 | struct test2::Double
+// CHECK-NEXT:   0:- |   int
+// CHECK-NEXT: 0 |   double d
+// CHECK-NEXT:   | [si

[PATCH] D78563: [AIX] Port power alignment rules to clang

2020-04-23 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L updated this revision to Diff 259559.
Xiangling_L marked 5 inline comments as done.
Xiangling_L added a comment.

Adjust some comments style;
Add more testcases;


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D78563/new/

https://reviews.llvm.org/D78563

Files:
  clang/include/clang/AST/RecordLayout.h
  clang/lib/AST/RecordLayout.cpp
  clang/lib/AST/RecordLayoutBuilder.cpp
  clang/test/Layout/aix-double-struct-member.cpp
  clang/test/Layout/aix-virtual-function-alignment.cpp

Index: clang/test/Layout/aix-virtual-function-alignment.cpp
===
--- /dev/null
+++ clang/test/Layout/aix-virtual-function-alignment.cpp
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -emit-llvm-only -triple powerpc-ibm-aix-xcoff \
+// RUN: -fdump-record-layouts -fsyntax-only %s 2>/dev/null | FileCheck \
+// RUN: --check-prefix=CHECK32 %s
+
+// RUN: %clang_cc1 -emit-llvm-only -triple powerpc64-ibm-aix-xcoff \
+// RUN: -fdump-record-layouts -fsyntax-only %s 2>/dev/null | FileCheck \
+// RUN: --check-prefix=CHECK64 %s
+
+struct A {
+  virtual void boo() {}
+};
+
+struct B {
+  bool b;
+  A a;
+};
+
+int i = sizeof(B);
+
+// CHECK32:  *** Dumping AST Record Layout
+// CHECK32-NEXT:  0 | struct A
+// CHECK32-NEXT:  0 |   (A vtable pointer)
+// CHECK32-NEXT:| [sizeof=4, dsize=4, align=4,
+// CHECK32-NEXT:|  nvsize=4, nvalign=4]
+
+// CHECK32:  *** Dumping AST Record Layout
+// CHECK32-NEXT:  0 | struct B
+// CHECK32-NEXT:  0 |   _Bool b
+// CHECK32-NEXT:  4 |   struct A a
+// CHECK32-NEXT:  4 | (A vtable pointer)
+// CHECK32-NEXT:| [sizeof=8, dsize=8, align=4,
+// CHECK32-NEXT:|  nvsize=8, nvalign=4]
+
+// CHECK64:  *** Dumping AST Record Layout
+// CHECK64-NEXT:  0 | struct A
+// CHECK64-NEXT:  0 |   (A vtable pointer)
+// CHECK64-NEXT:| [sizeof=8, dsize=8, align=8,
+// CHECK64-NEXT:|  nvsize=8, nvalign=8]
+
+// CHECK64:  *** Dumping AST Record Layout
+// CHECK64-NEXT:  0 | struct B
+// CHECK64-NEXT:  0 |   _Bool b
+// CHECK64-NEXT:  8 |   struct A a
+// CHECK64-NEXT:  8 | (A vtable pointer)
+// CHECK64-NEXT:| [sizeof=16, dsize=16, align=8,
+// CHECK64-NEXT:|  nvsize=16, nvalign=8]
Index: clang/test/Layout/aix-double-struct-member.cpp
===
--- /dev/null
+++ clang/test/Layout/aix-double-struct-member.cpp
@@ -0,0 +1,282 @@
+// RUN: %clang_cc1 -emit-llvm-only -triple powerpc-ibm-aix-xcoff \
+// RUN: -fdump-record-layouts -fsyntax-only %s 2>/dev/null | FileCheck %s
+
+// RUN: %clang_cc1 -emit-llvm-only -triple powerpc64-ibm-aix-xcoff \
+// RUN: -fdump-record-layouts -fsyntax-only %s 2>/dev/null | FileCheck %s
+
+namespace test1 {
+// Test double alignment when it is/is not the first struct member.
+struct D {
+  double d1;
+  int i1;
+};
+
+struct DoubleFirst {
+  struct D d2;
+  int i2;
+};
+
+struct IntFirst {
+  int i3;
+  struct D d3;
+};
+
+int a = sizeof(DoubleFirst);
+int b = sizeof(IntFirst);
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT: 0 | struct test1::D
+// CHECK-NEXT: 0 |   double d1
+// CHECK-NEXT: 8 |   int i1
+// CHECK-NEXT:   | [sizeof=16, dsize=16, align=8,
+// CHECK-NEXT:   |  nvsize=16, nvalign=8]
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT: 0 | struct test1::DoubleFirst
+// CHECK-NEXT: 0 |   struct test1::D d2
+// CHECK-NEXT: 0 | double d1
+// CHECK-NEXT: 8 | int i1
+// CHECK-NEXT:16 |   int i2
+// CHECK-NEXT:   | [sizeof=24, dsize=24, align=8,
+// CHECK-NEXT:   |  nvsize=24, nvalign=8]
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT: 0 | struct test1::IntFirst
+// CHECK-NEXT: 0 |   int i3
+// CHECK-NEXT: 4 |   struct test1::D d3
+// CHECK-NEXT: 4 | double d1
+// CHECK-NEXT:12 | int i1
+// CHECK-NEXT:   | [sizeof=20, dsize=20, align=4,
+// CHECK-NEXT:   |  nvsize=20, nvalign=4]
+}; // namespace test1
+
+namespace test2 {
+// Test AIX layout for zero sized bitfield followed by double.
+struct Double {
+  int : 0;
+  double d;
+};
+
+int a = sizeof(Double);
+
+// CHECK: *** Dumping AST Record Layout
+// CHECK-NEXT: 0 | struct test2::Double
+// CHECK-NEXT:   0:- |   int
+// CHECK-NEXT: 0 |   double d
+// CHECK-NEXT:   | [sizeof=8, dsize=8, align=4,
+// CHECK-NEXT:   |  nvsize=8, nvalign=4]
+}; // namespace test2
+
+namespace test3 {
+// Test the alignment of a double member in union.
+union A {
+  int *b;
+  double d;
+};
+
+struct UnionStruct {
+  union A a;
+  int i;
+};
+
+int a = sizeof(UnionStruct);
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:  0 | union test

[PATCH] D78563: [AIX] Port power alignment rules to clang

2020-04-27 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L abandoned this revision.
Xiangling_L added a comment.

Current implementation conflicts with  __AlignOf  behavior as we discussed in 
[RFC] Adding AIX power alignment rule in clang front end 
(http://lists.llvm.org/pipermail/cfe-dev/2020-April/065324.html) . Drop this 
revision and a new implementation will be put on Phabricator when it's ready.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D78563/new/

https://reviews.llvm.org/D78563



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D74166: [AIX][Frontend] Static init implementation for AIX considering no priority

2020-05-01 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L updated this revision to Diff 261602.
Xiangling_L added a comment.
Herald added a reviewer: aaron.ballman.

Fix a minor issue


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D74166/new/

https://reviews.llvm.org/D74166

Files:
  clang/include/clang/AST/Mangle.h
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/CodeGen/CGCXXABI.h
  clang/lib/CodeGen/CGDeclCXX.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/CodeGen/CodeGenModule.h
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/CodeGen/aix-priority-attribute.cpp
  clang/test/CodeGen/static-init.cpp

Index: clang/test/CodeGen/static-init.cpp
===
--- clang/test/CodeGen/static-init.cpp
+++ clang/test/CodeGen/static-init.cpp
@@ -1,12 +1,55 @@
-// RUN: not %clang_cc1 -triple powerpc-ibm-aix-xcoff -S -emit-llvm -x c++ %s \
-// RUN: -o /dev/null 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -triple powerpc-ibm-aix-xcoff -S -emit-llvm -x c++ < %s \
+// RUN: | FileCheck %s
 
-// RUN: not %clang_cc1 -triple powerpc64-ibm-aix-xcoff -S -emit-llvm -x c++ %s \
-// RUN: -o /dev/null 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -triple powerpc64-ibm-aix-xcoff -S -emit-llvm -x c++ < %s \
+// RUN: | FileCheck %s
 
 struct test {
   test();
   ~test();
 } t;
 
-// CHECK: error in backend: Static initialization has not been implemented on XL ABI yet.
+// CHECK: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @__sinit8000_clang_b2e4830f1c9d2d063e5ea946868f3bfd, i8* null }]
+// CHECK: @llvm.global_dtors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @__sterm8000_clang_b2e4830f1c9d2d063e5ea946868f3bfd, i8* null }]
+// CHECK: define dso_local void @__cxx_global_var_init() #0 {
+// CHECK: entry:
+// CHECK:   call void @_ZN4testC1Ev(%struct.test* @t)
+// CHECK:   %0 = call i32 @atexit(void ()* @__dtor_t)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define dso_local void @__dtor_t() #0 {
+// CHECK: entry:
+// CHECK:   call void @_ZN4testD1Ev(%struct.test* @t)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: declare i32 @atexit(void ()*) #3
+
+// CHECK: define dso_local void @__cxx_global_var_destruct_t() #0 {
+// CHECK: entry:
+// CHECK:   %0 = call i32 @unatexit(void ()* @__dtor_t)
+// CHECK:   %guard.hasSrterm = icmp eq i32 %0, 0
+// CHECK:   br i1 %guard.hasSrterm, label %destruct.check, label %destruct.end
+
+// CHECK: destruct.check:
+// CHECK:   call void @__dtor_t()
+// CHECK:   br label %destruct.end
+
+// CHECK: destruct.end:
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: declare i32 @unatexit(void ()*) #3
+
+// CHECK: define dso_local void @__sinit8000_clang_b2e4830f1c9d2d063e5ea946868f3bfd() #0 {
+// CHECK: entry:
+// CHECK:   call void @__cxx_global_var_init()
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define dso_local void @__sterm8000_clang_b2e4830f1c9d2d063e5ea946868f3bfd() #0 {
+// CHECK: entry:
+// CHECK:   call void @__cxx_global_var_destruct_t()
+// CHECK:   ret void
+// CHECK: }
Index: clang/test/CodeGen/aix-priority-attribute.cpp
===
--- /dev/null
+++ clang/test/CodeGen/aix-priority-attribute.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple powerpc-ibm-aix-xcoff -x c++ -emit-llvm < %s 2>&1 | \
+// RUN: FileCheck %s
+// RUN: %clang_cc1 -triple powerpc64-ibm-aix-xcoff -x c++ -emit-llvm < %s 2>&1 | \
+// RUN: FileCheck %s
+
+int foo() __attribute__((constructor(180)));
+int bar() __attribute__((destructor(180)));
+
+class test {
+   int a;
+public:
+test(int c) {a = c;}
+~test() {a = 0;}
+};
+
+__attribute__ ((init_priority (2000)))
+test t(1);
+
+// CHECK: warning: 'constructor' attribute argument not supported:
+// CHECK: int foo() __attribute__((constructor(180)));
+
+// CHECK: warning: 'destructor' attribute argument not supported:
+// check: int bar() __attribute__((destructor(180)));
+
+// CHECK: warning: 'init_priority' attribute argument not supported:
+// CHECK: __attribute__ ((init_priority (2000)))
Index: clang/lib/Sema/SemaDeclAttr.cpp
===
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -6895,13 +6895,19 @@
 handlePassObjectSizeAttr(S, D, AL);
 break;
   case ParsedAttr::AT_Constructor:
-handleConstructorAttr(S, D, AL);
+if (S.Context.getTargetInfo().getTriple().isOSAIX())
+  S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported) << AL << "";
+else
+  handleConstructorAttr(S, D, AL);
 break;
   case ParsedAttr::AT_Deprecated:
 handleDeprecatedAttr(S, D, AL);
 break;
   case ParsedAttr::AT_Destructor:
-handleDestructorAttr(S, D, AL);
+if (S.Context.getTargetInfo().getTriple().isOSAIX())
+  S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported) << AL << 

[PATCH] D85191: [AST] Get field size in chars rather than bits in RecordLayoutBuilder.

2020-08-04 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L added inline comments.



Comment at: clang/lib/AST/RecordLayoutBuilder.cpp:1841
   auto setDeclInfo = [&](bool IsIncompleteArrayType) {
-TypeInfo TI = Context.getTypeInfo(D->getType());
-FieldAlign = Context.toCharUnitsFromBits(TI.Align);
+auto TI = Context.getTypeInfoInChars(D->getType());
+FieldAlign = TI.second;

In most cases, `getTypeInfoInChars` invokes `getTypeInfo` underneath. So to 
make people be careful about this, I would suggest to leave a comment 
explaining/claiming we have to call `getTypeInfoInChars` here. And also maybe 
adding a testcase to guard the scenario you were talking about would be helpful 
to prevent someone to use `getTypeInfo` here in the future.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D85191/new/

https://reviews.llvm.org/D85191

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D84534: [AIX] Static init frontend recovery and backend support

2020-08-04 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L marked 6 inline comments as done.
Xiangling_L added inline comments.



Comment at: clang/lib/CodeGen/CodeGenModule.h:1058
+  /// Add an sterm finalizer to its own llvm.global_dtors entry.
+  void AddCXXStermFinalizerToGlobalDtor(llvm::Function *StermFinalizer,
+int Priority) {

jasonliu wrote:
> This wrapper seems redundant. Calling ` AddGlobalDtor(StermFinalizer, 
> Priority);` directly from the callee side already convey what we are trying 
> to achieve here. 
I added this wrapper function to keep the symmetry between `AddGlobalCtor` and 
`AddGlobalDtor`. They are private functions within `CodeGenModule` class. And I 
feel it's kinda weird to only move `AddGlobalDtor` to a public function.



Comment at: clang/lib/CodeGen/ItaniumCXXABI.cpp:4602
+llvm::report_fatal_error(
+"prioritized __sinit and __sterm functions are not yet supported");
+  else if (isTemplateInstantiation(D.getTemplateSpecializationKind()) ||

jasonliu wrote:
> Could we trigger this error? If so, could we have a test for it? 
I should've put an assertion here. The init priority attribute has been 
disabled on AIX in the previous patch.



Comment at: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1874
+  }
+  emitSpecialLLVMGlobal(&G);
+  continue;

jasonliu wrote:
> Have some suggestion on structure backend code change:
> 
> 1. Remove `isSpecialLLVMGlobalArrayForStaticInit` and 
> `isSpecialLLVMGlobalArrayToSkip`, and call `emitSpecialLLVMGlobal` directly 
> instead. This would handle all the `llvm.` variable for us. We would need do 
> early return for names start with `llvm.` in emitGlobalVariable as well, 
> since they are all handled here.
> 
> 2. We could override emitXXStructorList because how XCOFF handle the list is 
> vastly different than the other target. We could make the common part(i.e. 
> processing and sorting) a utility function, say "preprocessStructorList".
> 
> 3. It's not necessary to use the same name `emitXXStructor` if the interface 
> is different. It might not provide much help when we kinda know no other 
> target is going to use this interface. So we could turn it into a lambda 
> inside of the overrided emitXXStructorList, or simply no need for a new 
> function because the logic is fairly straightforward.
> 
1. As we discussed offline, we would leave the handling of `llvm.used` and 
`llvm.metadata` later and don't include them in the scope of this patch.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D84534/new/

https://reviews.llvm.org/D84534

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D84534: [AIX] Static init frontend recovery and backend support

2020-08-04 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L added inline comments.



Comment at: llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp:1865
+if (isSpecialLLVMGlobalArrayForStaticInit(&G)) {
+  if (GlobalUniqueModuleId.empty()) {
+GlobalUniqueModuleId = getUniqueModuleId(&M);

jasonliu wrote:
> We will need to move this part of the if statement to the overrided 
> `emitXXStructorList` as well. (If we think overriding `emitXXStructorList` 
> and calling `emitSpecialLLVMGlobal ` directly is a good idea.)
`getUniqueModuleId` takes `Module` as a parameter, if we want to invoke this 
function inside of `emitXXStructorList` through `emitSpecialLLVMGlobal`, we 
have to change the interface of them, which seems not ideal.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D84534/new/

https://reviews.llvm.org/D84534

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D84534: [AIX] Static init frontend recovery and backend support

2020-08-05 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L marked 7 inline comments as done.
Xiangling_L added inline comments.



Comment at: llvm/include/llvm/CodeGen/AsmPrinter.h:466
+
+  bool preprocessStructorList(const DataLayout &DL, const Constant *List,
+  SmallVector &Structors);

jasonliu wrote:
> A doxygen comment describe what this function does, and what its return value 
> means, and mention `Structors` is an output argument.
> By looking at what this function does, it seems `buildStructorList` is a 
> better name.
I meant to and should've named this function to `preprocessXXStructorList`, let 
me know if you still prefer `buildStructorList`. And if you do, since the 
underneath of `SmallVector` is a variable-sized array, maybe we should try 
`buildSortedStructorArray`?



Comment at: llvm/test/CodeGen/PowerPC/aix-static-init-key-object.ll:6
+
+@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, 
void ()*, i8* } { i32 65535, void ()* @foo, i8* @v}]
+

jasonliu wrote:
> Adding this test case would looks like we already decided how to handle .ref 
> in clang and llvm. But in fact, we haven't. I would prefer not having this 
> test.
As we discussed offline, I would adjust the error message instead.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D84534/new/

https://reviews.llvm.org/D84534

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D84534: [AIX] Static init frontend recovery and backend support

2020-08-05 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L updated this revision to Diff 283396.
Xiangling_L marked 2 inline comments as done.
Xiangling_L added a comment.

Added descriptions for struct and functions;
Addressed other comments;


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D84534/new/

https://reviews.llvm.org/D84534

Files:
  clang/lib/CodeGen/CGDeclCXX.cpp
  clang/lib/CodeGen/CodeGenModule.h
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/test/CodeGenCXX/aix-static-init-debug-info.cpp
  clang/test/CodeGenCXX/aix-static-init-temp-spec-and-inline-var.cpp
  clang/test/CodeGenCXX/aix-static-init.cpp
  clang/unittests/CodeGen/IncrementalProcessingTest.cpp
  llvm/include/llvm/CodeGen/AsmPrinter.h
  llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
  llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
  llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
  llvm/test/CodeGen/PowerPC/aix-static-init-default-priority.ll
  llvm/test/CodeGen/PowerPC/aix-static-init-key-object.ll
  llvm/test/CodeGen/PowerPC/aix-static-init-no-unique-module-id.ll
  llvm/test/CodeGen/PowerPC/aix-static-init-non-default-priority.ll

Index: llvm/test/CodeGen/PowerPC/aix-static-init-non-default-priority.ll
===
--- /dev/null
+++ llvm/test/CodeGen/PowerPC/aix-static-init-non-default-priority.ll
@@ -0,0 +1,10 @@
+; RUN: not llc -mtriple powerpc-ibm-aix-xcoff < %s 2>&1 | FileCheck %s
+; RUN: not llc -mtriple powerpc64-ibm-aix-xcoff < %s 2>&1 | FileCheck %s
+
+@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 655, void ()* @foo, i8* null }]
+
+define void @foo() {
+  ret void
+}
+
+// CHECK: LLVM ERROR: prioritized sinit and sterm functions are not yet supported
Index: llvm/test/CodeGen/PowerPC/aix-static-init-no-unique-module-id.ll
===
--- /dev/null
+++ llvm/test/CodeGen/PowerPC/aix-static-init-no-unique-module-id.ll
@@ -0,0 +1,7 @@
+; RUN: not llc -mtriple powerpc-ibm-aix-xcoff < %s 2>&1 | FileCheck %s
+; RUN: not llc -mtriple powerpc64-ibm-aix-xcoff < %s 2>&1 | FileCheck %s
+
+@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @foo, i8* null }]
+@llvm.global_dtors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @bar, i8* null }]
+
+// CHECK: LLVM ERROR: cannot produce a unique identifier for this module based on strong external symbols
Index: llvm/test/CodeGen/PowerPC/aix-static-init-key-object.ll
===
--- /dev/null
+++ llvm/test/CodeGen/PowerPC/aix-static-init-key-object.ll
@@ -0,0 +1,12 @@
+; RUN: not llc -mtriple powerpc-ibm-aix-xcoff < %s 2>&1 | FileCheck %s
+; RUN: not llc -mtriple powerpc64-ibm-aix-xcoff < %s 2>&1 | FileCheck %s
+
+@v = global i8 0
+
+@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @foo, i8* @v}]
+
+define void @foo() {
+  ret void
+}
+
+// CHECK: LLVM ERROR: associated data of XXStructor list is not yet supported on AIX
Index: llvm/test/CodeGen/PowerPC/aix-static-init-default-priority.ll
===
--- /dev/null
+++ llvm/test/CodeGen/PowerPC/aix-static-init-default-priority.ll
@@ -0,0 +1,60 @@
+; RUN: llc -mtriple powerpc-ibm-aix-xcoff < %s | FileCheck %s
+; RUN: llc -mtriple powerpc64-ibm-aix-xcoff < %s | FileCheck %s
+
+@llvm.global_ctors = appending global [2 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @init1, i8* null }, { i32, void ()*, i8* } { i32 65535, void ()* @init2, i8* null }]
+@llvm.global_dtors = appending global [2 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @destruct1, i8* null }, { i32, void ()*, i8* } { i32 65535, void ()* @destruct2, i8* null }]
+
+define i32 @extFunc() {
+entry:
+  ret i32 3
+}
+
+define internal void @init1() {
+  ret void
+}
+
+define internal void @destruct1() {
+  ret void
+}
+
+define internal void @init2() {
+  ret void
+}
+
+define internal void @destruct2() {
+  ret void
+}
+
+; CHECK:   .lglobl	init1[DS]
+; CHECK:   .lglobl	.init1
+; CHECK:   .csect init1[DS]
+; CHECK: __sinit8000_clang_ac404299654d2af7eae71e75c17f7c9b_0: # @init1
+; CHECK: .init1:
+; CHECK: .__sinit8000_clang_ac404299654d2af7eae71e75c17f7c9b_0:
+; CHECK:   .lglobl	destruct1[DS]
+; CHECK:   .lglobl	.destruct1
+; CHECK:   .csect destruct1[DS]
+; CHECK: __sterm8000_clang_ac404299654d2af7eae71e75c17f7c9b_0: # @destruct1
+; CHECK: .destruct1:
+; CHECK: .__sterm8000_clang_ac404299654d2af7eae71e75c17f7c9b_0:
+; CHECK:   .lglobl	init2[DS]
+; CHECK:   .lglobl	.init2
+; CHECK:   .csect init2[DS]
+; CHECK: __sinit8000_clang_ac404299654d2af7eae71e75c17f7c9b_1: # @init2
+; CHECK: .init2:
+; CHECK: .__sinit8000_clang_ac404299654d2af7eae71e75c17f7c9b_1:
+; CHECK:   .lglobl	destruct2[D

[PATCH] D84534: [AIX] Static init frontend recovery and backend support

2020-08-06 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L marked 5 inline comments as done.
Xiangling_L added inline comments.



Comment at: llvm/include/llvm/CodeGen/AsmPrinter.h:466
+
+  bool preprocessStructorList(const DataLayout &DL, const Constant *List,
+  SmallVector &Structors);

jasonliu wrote:
> Xiangling_L wrote:
> > jasonliu wrote:
> > > A doxygen comment describe what this function does, and what its return 
> > > value means, and mention `Structors` is an output argument.
> > > By looking at what this function does, it seems `buildStructorList` is a 
> > > better name.
> > I meant to and should've named this function to `preprocessXXStructorList`, 
> > let me know if you still prefer `buildStructorList`. And if you do, since 
> > the underneath of `SmallVector` is a variable-sized array, maybe we should 
> > try `buildSortedStructorArray`?
> `preprocess` sounds like we are already having a XXStructorList and now we 
> try to do something on it. 
> But right now, we are actually passing in an empty StructorList/Array and 
> build it from scratch. So I would still prefer the name of `build` in it.
> I don't mind changing to a more accurate name as you suggested. 
I think we do have a `XXStructorList` here which is the initializer of 
`llvm.gloal_ctors`or `llvm.gloal_dtors` array? The usage of this term is  
consistent with other spots.



Comment at: llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp:2107
+  if (!isa(List))
+return false;
 

jasonliu wrote:
> Return of boolean seems unnecessary. 
> Callee could check the size of the Structors to decide if they want an early 
> return or not (or in this particular case, the for loop would just do nothing 
> and no need for extra condition if you don't mind the call to 
> getPointerPrefAlignment or assign to 0 to Index)?
> So we could just return void for this function?
Yeah, we could do that. But it looks a boolean return value makes the code flow 
natural. And if any target does want to control the early return in the future, 
it's flexbile for them to do that. I am wondering is there any big difference 
between bool and void return value for this function? 


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D84534/new/

https://reviews.llvm.org/D84534

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D84534: [AIX] Static init frontend recovery and backend support

2020-08-06 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L marked 3 inline comments as done.
Xiangling_L added inline comments.



Comment at: llvm/include/llvm/CodeGen/AsmPrinter.h:466
+
+  bool preprocessStructorList(const DataLayout &DL, const Constant *List,
+  SmallVector &Structors);

jasonliu wrote:
> Xiangling_L wrote:
> > jasonliu wrote:
> > > Xiangling_L wrote:
> > > > jasonliu wrote:
> > > > > A doxygen comment describe what this function does, and what its 
> > > > > return value means, and mention `Structors` is an output argument.
> > > > > By looking at what this function does, it seems `buildStructorList` 
> > > > > is a better name.
> > > > I meant to and should've named this function to 
> > > > `preprocessXXStructorList`, let me know if you still prefer 
> > > > `buildStructorList`. And if you do, since the underneath of 
> > > > `SmallVector` is a variable-sized array, maybe we should try 
> > > > `buildSortedStructorArray`?
> > > `preprocess` sounds like we are already having a XXStructorList and now 
> > > we try to do something on it. 
> > > But right now, we are actually passing in an empty StructorList/Array and 
> > > build it from scratch. So I would still prefer the name of `build` in it.
> > > I don't mind changing to a more accurate name as you suggested. 
> > I think we do have a `XXStructorList` here which is the initializer of 
> > `llvm.gloal_ctors`or `llvm.gloal_dtors` array? The usage of this term is  
> > consistent with other spots.
> My understanding is that before we enter this `preprocessXXStructorList`, we 
> do not have a list of XXStructor. We only have a list of `Constant`. This 
> functions turns a list of `Constant` to a list of `XXStructor`. 
Just leave a record here, as we discussed offline, we agree that the meaning of 
term `XXStructorList` is `the initializer of `llvm.gloal_ctors` or 
`llvm.gloal_dtors` array. So I will keep using `preprocessXXStructorList` as 
the function name.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D84534/new/

https://reviews.llvm.org/D84534

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D84534: [AIX] Static init frontend recovery and backend support

2020-08-06 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L updated this revision to Diff 283712.
Xiangling_L marked an inline comment as done.

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D84534/new/

https://reviews.llvm.org/D84534

Files:
  clang/lib/CodeGen/CGDeclCXX.cpp
  clang/lib/CodeGen/CodeGenModule.h
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/test/CodeGenCXX/aix-static-init-debug-info.cpp
  clang/test/CodeGenCXX/aix-static-init-temp-spec-and-inline-var.cpp
  clang/test/CodeGenCXX/aix-static-init.cpp
  clang/unittests/CodeGen/IncrementalProcessingTest.cpp
  llvm/include/llvm/CodeGen/AsmPrinter.h
  llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
  llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
  llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
  llvm/test/CodeGen/PowerPC/aix-static-init-default-priority.ll
  llvm/test/CodeGen/PowerPC/aix-static-init-key-object.ll
  llvm/test/CodeGen/PowerPC/aix-static-init-no-unique-module-id.ll
  llvm/test/CodeGen/PowerPC/aix-static-init-non-default-priority.ll

Index: llvm/test/CodeGen/PowerPC/aix-static-init-non-default-priority.ll
===
--- /dev/null
+++ llvm/test/CodeGen/PowerPC/aix-static-init-non-default-priority.ll
@@ -0,0 +1,10 @@
+; RUN: not llc -mtriple powerpc-ibm-aix-xcoff < %s 2>&1 | FileCheck %s
+; RUN: not llc -mtriple powerpc64-ibm-aix-xcoff < %s 2>&1 | FileCheck %s
+
+@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 655, void ()* @foo, i8* null }]
+
+define void @foo() {
+  ret void
+}
+
+// CHECK: LLVM ERROR: prioritized sinit and sterm functions are not yet supported
Index: llvm/test/CodeGen/PowerPC/aix-static-init-no-unique-module-id.ll
===
--- /dev/null
+++ llvm/test/CodeGen/PowerPC/aix-static-init-no-unique-module-id.ll
@@ -0,0 +1,7 @@
+; RUN: not llc -mtriple powerpc-ibm-aix-xcoff < %s 2>&1 | FileCheck %s
+; RUN: not llc -mtriple powerpc64-ibm-aix-xcoff < %s 2>&1 | FileCheck %s
+
+@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @foo, i8* null }]
+@llvm.global_dtors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @bar, i8* null }]
+
+// CHECK: LLVM ERROR: cannot produce a unique identifier for this module based on strong external symbols
Index: llvm/test/CodeGen/PowerPC/aix-static-init-key-object.ll
===
--- /dev/null
+++ llvm/test/CodeGen/PowerPC/aix-static-init-key-object.ll
@@ -0,0 +1,12 @@
+; RUN: not llc -mtriple powerpc-ibm-aix-xcoff < %s 2>&1 | FileCheck %s
+; RUN: not llc -mtriple powerpc64-ibm-aix-xcoff < %s 2>&1 | FileCheck %s
+
+@v = global i8 0
+
+@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @foo, i8* @v}]
+
+define void @foo() {
+  ret void
+}
+
+// CHECK: LLVM ERROR: associated data of XXStructor list is not yet supported on AIX
Index: llvm/test/CodeGen/PowerPC/aix-static-init-default-priority.ll
===
--- /dev/null
+++ llvm/test/CodeGen/PowerPC/aix-static-init-default-priority.ll
@@ -0,0 +1,60 @@
+; RUN: llc -mtriple powerpc-ibm-aix-xcoff < %s | FileCheck %s
+; RUN: llc -mtriple powerpc64-ibm-aix-xcoff < %s | FileCheck %s
+
+@llvm.global_ctors = appending global [2 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @init1, i8* null }, { i32, void ()*, i8* } { i32 65535, void ()* @init2, i8* null }]
+@llvm.global_dtors = appending global [2 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @destruct1, i8* null }, { i32, void ()*, i8* } { i32 65535, void ()* @destruct2, i8* null }]
+
+define i32 @extFunc() {
+entry:
+  ret i32 3
+}
+
+define internal void @init1() {
+  ret void
+}
+
+define internal void @destruct1() {
+  ret void
+}
+
+define internal void @init2() {
+  ret void
+}
+
+define internal void @destruct2() {
+  ret void
+}
+
+; CHECK:   .lglobl	init1[DS]
+; CHECK:   .lglobl	.init1
+; CHECK:   .csect init1[DS]
+; CHECK: __sinit8000_clang_ac404299654d2af7eae71e75c17f7c9b_0: # @init1
+; CHECK: .init1:
+; CHECK: .__sinit8000_clang_ac404299654d2af7eae71e75c17f7c9b_0:
+; CHECK:   .lglobl	destruct1[DS]
+; CHECK:   .lglobl	.destruct1
+; CHECK:   .csect destruct1[DS]
+; CHECK: __sterm8000_clang_ac404299654d2af7eae71e75c17f7c9b_0: # @destruct1
+; CHECK: .destruct1:
+; CHECK: .__sterm8000_clang_ac404299654d2af7eae71e75c17f7c9b_0:
+; CHECK:   .lglobl	init2[DS]
+; CHECK:   .lglobl	.init2
+; CHECK:   .csect init2[DS]
+; CHECK: __sinit8000_clang_ac404299654d2af7eae71e75c17f7c9b_1: # @init2
+; CHECK: .init2:
+; CHECK: .__sinit8000_clang_ac404299654d2af7eae71e75c17f7c9b_1:
+; CHECK:   .lglobl	destruct2[DS]
+; CHECK:   .lglobl	.destruct2
+; CHECK:   .csect destruct2[DS]
+; CHECK: __sterm8000_c

[PATCH] D84534: [AIX] Static init frontend recovery and backend support

2020-08-10 Thread Xiangling Liao via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG6ef801aa6bc0: [AIX] Static init frontend recovery and 
backend support (authored by Xiangling_L).

Changed prior to commit:
  https://reviews.llvm.org/D84534?vs=283712&id=284355#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D84534/new/

https://reviews.llvm.org/D84534

Files:
  clang/lib/CodeGen/CGDeclCXX.cpp
  clang/lib/CodeGen/CodeGenModule.h
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/test/CodeGenCXX/aix-static-init-debug-info.cpp
  clang/test/CodeGenCXX/aix-static-init-temp-spec-and-inline-var.cpp
  clang/test/CodeGenCXX/aix-static-init.cpp
  clang/unittests/CodeGen/IncrementalProcessingTest.cpp
  llvm/include/llvm/CodeGen/AsmPrinter.h
  llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
  llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
  llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp
  llvm/test/CodeGen/PowerPC/aix-static-init-default-priority.ll
  llvm/test/CodeGen/PowerPC/aix-static-init-key-object.ll
  llvm/test/CodeGen/PowerPC/aix-static-init-no-unique-module-id.ll
  llvm/test/CodeGen/PowerPC/aix-static-init-non-default-priority.ll

Index: llvm/test/CodeGen/PowerPC/aix-static-init-non-default-priority.ll
===
--- /dev/null
+++ llvm/test/CodeGen/PowerPC/aix-static-init-non-default-priority.ll
@@ -0,0 +1,10 @@
+; RUN: not --crash llc -mtriple powerpc-ibm-aix-xcoff < %s 2>&1 | FileCheck %s
+; RUN: not --crash llc -mtriple powerpc64-ibm-aix-xcoff < %s 2>&1 | FileCheck %s
+
+@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 655, void ()* @foo, i8* null }]
+
+define void @foo() {
+  ret void
+}
+
+; CHECK: LLVM ERROR: prioritized sinit and sterm functions are not yet supported
Index: llvm/test/CodeGen/PowerPC/aix-static-init-no-unique-module-id.ll
===
--- /dev/null
+++ llvm/test/CodeGen/PowerPC/aix-static-init-no-unique-module-id.ll
@@ -0,0 +1,10 @@
+; RUN: not --crash llc -mtriple powerpc-ibm-aix-xcoff %s 2>&1 | FileCheck %s
+; RUN: not --crash llc -mtriple powerpc64-ibm-aix-xcoff %s 2>&1 | FileCheck %s
+
+@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @foo, i8* null }]
+
+define internal void @foo() {
+  ret void
+}
+
+; CHECK: LLVM ERROR: cannot produce a unique identifier for this module based on strong external symbols
Index: llvm/test/CodeGen/PowerPC/aix-static-init-key-object.ll
===
--- /dev/null
+++ llvm/test/CodeGen/PowerPC/aix-static-init-key-object.ll
@@ -0,0 +1,12 @@
+; RUN: not --crash llc -mtriple powerpc-ibm-aix-xcoff < %s 2>&1 | FileCheck %s
+; RUN: not --crash llc -mtriple powerpc64-ibm-aix-xcoff < %s 2>&1 | FileCheck %s
+
+@v = global i8 0
+
+@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @foo, i8* @v}]
+
+define void @foo() {
+  ret void
+}
+
+; CHECK: LLVM ERROR: associated data of XXStructor list is not yet supported on AIX
Index: llvm/test/CodeGen/PowerPC/aix-static-init-default-priority.ll
===
--- /dev/null
+++ llvm/test/CodeGen/PowerPC/aix-static-init-default-priority.ll
@@ -0,0 +1,60 @@
+; RUN: llc -mtriple powerpc-ibm-aix-xcoff < %s | FileCheck %s
+; RUN: llc -mtriple powerpc64-ibm-aix-xcoff < %s | FileCheck %s
+
+@llvm.global_ctors = appending global [2 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @init1, i8* null }, { i32, void ()*, i8* } { i32 65535, void ()* @init2, i8* null }]
+@llvm.global_dtors = appending global [2 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @destruct1, i8* null }, { i32, void ()*, i8* } { i32 65535, void ()* @destruct2, i8* null }]
+
+define i32 @extFunc() {
+entry:
+  ret i32 3
+}
+
+define internal void @init1() {
+  ret void
+}
+
+define internal void @destruct1() {
+  ret void
+}
+
+define internal void @init2() {
+  ret void
+}
+
+define internal void @destruct2() {
+  ret void
+}
+
+; CHECK:   .lglobl	init1[DS]
+; CHECK:   .lglobl	.init1
+; CHECK:   .csect init1[DS]
+; CHECK: __sinit8000_clang_ac404299654d2af7eae71e75c17f7c9b_0: # @init1
+; CHECK: .init1:
+; CHECK: .__sinit8000_clang_ac404299654d2af7eae71e75c17f7c9b_0:
+; CHECK:   .lglobl	destruct1[DS]
+; CHECK:   .lglobl	.destruct1
+; CHECK:   .csect destruct1[DS]
+; CHECK: __sterm8000_clang_ac404299654d2af7eae71e75c17f7c9b_0: # @destruct1
+; CHECK: .destruct1:
+; CHECK: .__sterm8000_clang_ac404299654d2af7eae71e75c17f7c9b_0:
+; CHECK:   .lglobl	init2[DS]
+; CHECK:   .lglobl	.init2
+; CHECK:   .csect init2[DS]
+; CHECK: __sinit8000_clang_ac404299654d2af7eae71e75c17f7c9b_1: # @init2
+; CHECK: .init2:
+; CHECK: .__sinit8000_cla

[PATCH] D79035: [clang][AIX] Implement ABIInfo and TargetCodeGenInfo for AIX

2020-05-04 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L added inline comments.



Comment at: clang/lib/CodeGen/TargetInfo.cpp:4179
+  // This is calculated from the LLVM and GCC tables and verified
+  // against gcc output.  AFAIK all ABIs use the same encoding.
+

Minor comment about comment style:
Though I noticed that "AFAIK all ABIs use the same encoding." is from original 
code, could we adjust it to something like "All PPC ABIs use the same encoding."



Comment at: clang/lib/CodeGen/TargetInfo.cpp:4194
+
+  // 64-76 are various 4-byte or 8-byte special-purpose registers:
+  // 64: mq

s/64-76/64-67?



Comment at: clang/lib/CodeGen/TargetInfo.cpp:4317
+  if (isAggregateTypeForABI(RetTy))
+return getNaturalAlignIndirect(RetTy);
+

This method uses the ABI alignment of the given aggregate type which I think is 
not ideal due to our AIX special alignment rule. We need to use preferred 
alignment in this case.
Btw also I think it's not necessary for you to rebase your patch on the power 
alignment patch, I can refresh the testcase when I am dealing with that one.



Comment at: clang/lib/CodeGen/TargetInfo.cpp:4336
+if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI()))
+  return getNaturalAlignIndirect(Ty, RAA == CGCXXABI::RAA_DirectInMemory);
+

Same comment like above.



Comment at: clang/test/CodeGen/aix-vaargs.c:3
+// REQUIRES: asserts
+// RUN: %clang_cc1 -triple powerpc-unknown-aix -emit-llvm -o - %s | FileCheck 
%s --check-prefixes=AIX-COM,AIX-M32
+// RUN: %clang_cc1 -triple powerpc64-unknown-aix -emit-llvm -o - %s | 
FileCheck %s --check-prefixes=AIX-COM,AIX-M64

Consistent with other testcases to use `AIX32/AIX64`?



Comment at: clang/test/CodeGen/ppc32-and-aix-struct-return.c:8
+// RUN:   -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-AIX
+// RUN: %clang_cc1 -triple powerpc-unknown-linux \
+// RUN:   -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-AIX

Do you mean to check AIX or SVR4?



Comment at: clang/test/CodeGen/ppc32-dwarf.c:2
+// RUN: %clang_cc1 -triple powerpc-unknown-aix -emit-llvm %s -o - | FileCheck 
%s
+// RUN: %clang_cc1 -triple powerpc-unknown-unknown -emit-llvm %s -o - | 
FileCheck %s --check-prefixes=CHECK,PPC32
+static unsigned char dwarf_reg_size_table[1024];

Minor comment:
Would `PPC32SVR4` compared to `PPC32` make the checking content clearer since 
PPC32 actually includes AIX target?



Comment at: clang/test/CodeGen/ppc64-dwarf.c:2
+// RUN: %clang_cc1 -triple powerpc64-unknown-aix -emit-llvm %s -o - | 
FileCheck %s
+// RUN: %clang_cc1 -triple powerpc64-unknown-unknown -emit-llvm %s -o - | 
FileCheck %s --check-prefixes=CHECK,PPC64
 static unsigned char dwarf_reg_size_table[1024];

Same comment as above.
s/PPC64/PPC64SVR4?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79035/new/

https://reviews.llvm.org/D79035



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D79035: [clang][AIX] Implement ABIInfo and TargetCodeGenInfo for AIX

2020-05-05 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L added inline comments.



Comment at: clang/lib/CodeGen/TargetInfo.cpp:4317
+  if (isAggregateTypeForABI(RetTy))
+return getNaturalAlignIndirect(RetTy);
+

jasonliu wrote:
> Xiangling_L wrote:
> > This method uses the ABI alignment of the given aggregate type which I 
> > think is not ideal due to our AIX special alignment rule. We need to use 
> > preferred alignment in this case.
> > Btw also I think it's not necessary for you to rebase your patch on the 
> > power alignment patch, I can refresh the testcase when I am dealing with 
> > that one.
> As it is right now in master, there is no difference between natural 
> alignment and preferred alignment for AIX. The tentative direction is to use 
> preferred alignment to record the actual alignment on AIX, but it is not 
> finalized yet. I would rather leave this part of the work for the patch 
> that's going to implement the power alignment rule for AIX.
`getNaturalAlignIndirect` uses ABI align which is for sure not correct on AIX 
target for Aggregate types. What we want is the actual alignment here.

So I am not sure if we want to take `getNaturalAlignIndirect` for granted even 
if we know it's not correct semantically.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79035/new/

https://reviews.llvm.org/D79035



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D79035: [clang][AIX] Implement ABIInfo and TargetCodeGenInfo for AIX

2020-05-05 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L added inline comments.



Comment at: clang/lib/CodeGen/TargetInfo.cpp:4317
+  if (isAggregateTypeForABI(RetTy))
+return getNaturalAlignIndirect(RetTy);
+

Xiangling_L wrote:
> jasonliu wrote:
> > Xiangling_L wrote:
> > > This method uses the ABI alignment of the given aggregate type which I 
> > > think is not ideal due to our AIX special alignment rule. We need to use 
> > > preferred alignment in this case.
> > > Btw also I think it's not necessary for you to rebase your patch on the 
> > > power alignment patch, I can refresh the testcase when I am dealing with 
> > > that one.
> > As it is right now in master, there is no difference between natural 
> > alignment and preferred alignment for AIX. The tentative direction is to 
> > use preferred alignment to record the actual alignment on AIX, but it is 
> > not finalized yet. I would rather leave this part of the work for the patch 
> > that's going to implement the power alignment rule for AIX.
> `getNaturalAlignIndirect` uses ABI align which is for sure not correct on AIX 
> target for Aggregate types. What we want is the actual alignment here.
> 
> So I am not sure if we want to take `getNaturalAlignIndirect` for granted 
> even if we know it's not correct semantically.
Comment update:
For the power alignment patch, after some investigation, to test IR alignment 
value for struct as argument and return type, it should base on this ABI patch. 

So I agree that we can rely on power alignment patch later to update this part.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79035/new/

https://reviews.llvm.org/D79035



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D79035: [clang][AIX] Implement ABIInfo and TargetCodeGenInfo for AIX

2020-05-08 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L added inline comments.



Comment at: clang/lib/CodeGen/TargetInfo.cpp:1547
 
   // Otherwise, if the type contains an SSE vector type, the alignment is 16.
+  if (Align >= 16 && (isSIMDVectorType(getContext(), Ty) ||

Also update the comment?



Comment at: clang/lib/CodeGen/TargetInfo.cpp:4365
+
+  Ty = useFirstFieldIfTransparentUnion(Ty);
+

As in doc says [[ 
https://www.ibm.com/support/knowledgecenter/SSGH2K_13.1.0/com.ibm.xlc131.aix.doc/language_ref/type_attr_transp_union.html
 | The transparent_union type attribute ]]:
 `float _Complex, double _Complex or vector types can be members of a 
transparent union, but they cannot be the first member. `  That means the first 
field still could be something like Integral Complex etc., which falls into the 
category `isAnyComplexType`.

So I guess `Ty = useFirstFieldIfTransparentUnion(Ty);` should be at the first 
line.



Comment at: clang/lib/CodeGen/TargetInfo.cpp:4374
+CharUnits ABIAlign = getParamTypeAlignment(Ty);
+CharUnits TyAlign = getContext().getTypeAlignInChars(Ty);
+

If we want to be consistent with other part of alignment implementation, 
`getContext().getTypeAlignInChars(Ty)` gives `ABIAlign`. I would suggest we 
name `ABIAlign` here to something like `CCAlign` or `ArgumentAlign`.



Comment at: clang/lib/CodeGen/TargetInfo.cpp:4684
 return false;
   case CodeGenOptions::SRCK_InRegs: // -msvr4-struct-return
 return true;

I noticed that in patch https://reviews.llvm.org/D76360, Zarko added a check to 
emit an error for using this option within cc1. But in your patch, this option 
only emit error when invoked by the driver. Does that mean we are pretty sure 
this option is doing what we want on AIX?


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79035/new/

https://reviews.llvm.org/D79035



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D79719: [AIX] Implement AIX special alignment rule about double/long double

2020-05-11 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L created this revision.
Xiangling_L added reviewers: hubert.reinterpretcast, jasonliu, sfertile, 
cebowleratibm.
Xiangling_L added a project: LLVM.
Herald added subscribers: cfe-commits, kbarton, nemanjai.
Herald added a project: clang.

Implement AIX special alignment rule by recursively checking if the
'real' first member is a double/long double. If yes, then this member
should be naturally aligned to 8 rather than 4.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D79719

Files:
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/AST/RecordLayout.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/RecordLayout.cpp
  clang/lib/AST/RecordLayoutBuilder.cpp
  clang/lib/Basic/Targets/PPC.h
  clang/test/Layout/aix-double-struct-member.cpp
  clang/test/Layout/aix-no-unique-address-with-double.cpp
  clang/test/Layout/aix-virtual-function-and-base-with-double.cpp

Index: clang/test/Layout/aix-virtual-function-and-base-with-double.cpp
===
--- /dev/null
+++ clang/test/Layout/aix-virtual-function-and-base-with-double.cpp
@@ -0,0 +1,112 @@
+// RUN: %clang_cc1 -emit-llvm-only -triple powerpc-ibm-aix-xcoff \
+// RUN: -fdump-record-layouts -fsyntax-only %s 2>/dev/null | FileCheck \
+// RUN: --check-prefixes=CHECK,CHECK32 %s
+
+// RUN: %clang_cc1 -emit-llvm-only -triple powerpc64-ibm-aix-xcoff \
+// RUN: -fdump-record-layouts -fsyntax-only %s 2>/dev/null | FileCheck \
+// RUN: --check-prefixes=CHECK,CHECK64 %s
+
+namespace test1 {
+struct A {
+  double d1;
+  virtual void boo() {}
+};
+
+struct B {
+  double d2;
+  A a;
+};
+
+struct C : public A {
+  double d3;
+};
+
+int i = sizeof(B);
+int j = sizeof(C);
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::A
+// CHECK-NEXT:0 |   (A vtable pointer)
+// CHECK32-NEXT:  4 |   double d1
+// CHECK32-NEXT:| [sizeof=12, dsize=12, align=4,
+// CHECK32-NEXT:|  nvsize=12, nvalign=4]
+// CHECK64-NEXT:  8 |   double d1
+// CHECK64-NEXT:| [sizeof=16, dsize=16, align=8,
+// CHECK64-NEXT:|  nvsize=16, nvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::B
+// CHECK-NEXT:0 |   double d2
+// CHECK-NEXT:8 |   struct test1::A a
+// CHECK-NEXT:8 | (A vtable pointer)
+// CHECK32-NEXT: 12 | double d1
+// CHECK32-NEXT:| [sizeof=24, dsize=20, align=8,
+// CHECK32-NEXT:|  nvsize=20, nvalign=8]
+// CHECK64-NEXT: 16 | double d1
+// CHECK64-NEXT:| [sizeof=24, dsize=24, align=8,
+// CHECK64-NEXT:|  nvsize=24, nvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test1::C
+// CHECK-NEXT:0 |   struct test1::A (primary base)
+// CHECK-NEXT:0 | (A vtable pointer)
+// CHECK32-NEXT:  4 | double d1
+// CHECK32-NEXT: 12 |   double d3
+// CHECK32-NEXT:| [sizeof=20, dsize=20, align=4,
+// CHECK32-NEXT:|  nvsize=20, nvalign=4]
+// CHECK64-NEXT:  8 | double d1
+// CHECK64-NEXT: 16 |   double d3
+// CHECK64-NEXT:| [sizeof=24, dsize=24, align=8,
+// CHECK64-NEXT:|  nvsize=24, nvalign=8]
+
+}; // namespace test1
+
+namespace test2 {
+struct A {
+  long long l1;
+};
+
+struct B : public virtual A {
+  double d2;
+};
+
+#pragma pack(2)
+struct C : public virtual A {
+  double __attribute__((aligned(4))) d3;
+};
+
+int i = sizeof(B);
+int j = sizeof(C);
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::A
+// CHECK-NEXT:0 |   long long l1
+// CHECK-NEXT:  | [sizeof=8, dsize=8, align=8,
+// CHECK-NEXT:  |  nvsize=8, nvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::B
+// CHECK-NEXT:0 |   (B vtable pointer)
+// CHECK32-NEXT:  4 |   double d2
+// CHECK64-NEXT:  8 |   double d2
+// CHECK-NEXT:   16 |   struct test2::A (virtual base)
+// CHECK-NEXT:   16 | long long l1
+// CHECK-NEXT:  | [sizeof=24, dsize=24, align=8,
+// CHECK32-NEXT:|  nvsize=12, nvalign=4]
+// CHECK64-NEXT:|  nvsize=16, nvalign=8]
+
+// CHECK:  *** Dumping AST Record Layout
+// CHECK-NEXT:0 | struct test2::C
+// CHECK-NEXT:0 |   (C vtable pointer)
+// CHECK32-NEXT:  4 |   double d3
+// CHECK32-NEXT: 12 |   struct test2::A (virtual base)
+// CHECK32-NEXT: 12 | long long l1
+// CHECK32-NEXT:| [sizeof=20, dsize=20, align=2,
+// CHECK32-NEXT:|  nvsize=12, nvalign=2]
+// CHECK64-NEXT:  8 |   double d3
+// CHECK64-NEXT: 16 |   struct test2::A (virtual base)
+// CHECK64-NEXT: 16 | long long l1
+// CHECK64-NEXT: 

[PATCH] D79035: [clang][AIX] Implement ABIInfo and TargetCodeGenInfo for AIX

2020-05-12 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L added inline comments.



Comment at: clang/lib/CodeGen/TargetInfo.cpp:4684
 return false;
   case CodeGenOptions::SRCK_InRegs: // -msvr4-struct-return
 return true;

jasonliu wrote:
> Xiangling_L wrote:
> > I noticed that in patch https://reviews.llvm.org/D76360, Zarko added a 
> > check to emit an error for using this option within cc1. But in your patch, 
> > this option only emit error when invoked by the driver. Does that mean we 
> > are pretty sure this option is doing what we want on AIX?
> Are you able to set this CodeGen option when it is disabled in the 
> Frontend/CompilerInvocation.cpp?
I would say if you disable it in this function 
`PPC32TargetCodeGenInfo::isStructReturnInRegABI`, neither driver and FE can 
invoke it. However, in your patch, the option is disabled only in the driver, 
that means you can still invoke it with clang_cc1.



Comment at: clang/test/CodeGen/aix-vector.c:11
+}
+

Please remove the extra blank line


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79035/new/

https://reviews.llvm.org/D79035



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D74166: [AIX][Frontend] Static init implementation for AIX considering no priority

2020-05-12 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L marked 7 inline comments as done.
Xiangling_L added inline comments.



Comment at: clang/lib/CodeGen/CGDeclCXX.cpp:691
   AddGlobalDtor(Fn);
+  CXXGlobalDtors.clear();
 }

ZarkoCA wrote:
> I may be missing something but why do we need this now, as opposed to not 
> needing it before? Why didn't we need to clear the CXXGlobalDtors after 
> emitting the function function before?
No, you didn't miss anything here. I just followed what 
`EmitCXXGlobalInitFunc()` does, which is to clear the std::vecotr once we are 
certain it's useless.



Comment at: clang/lib/Sema/SemaDeclAttr.cpp:6898
   case ParsedAttr::AT_Constructor:
-handleConstructorAttr(S, D, AL);
+if (S.Context.getTargetInfo().getTriple().isOSAIX())
+  S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported) << AL << "";

aaron.ballman wrote:
> This change (and the others like it) should be done within Attr.td and not 
> exposed here. You should make these attributes target-specific.
> 
> You should also update AttrDocs.td for these attributes to document that 
> they're not supported on AIX.
Thanks for your comments. As I mentioned in the below testcase, those three 
attributes actually will be supported by the follow-up patches for AIX.  I will 
update them to `report_fatal_error` instead.



Comment at: clang/test/CodeGen/aix-priority-attribute.cpp:1-4
+// RUN: %clang_cc1 -triple powerpc-ibm-aix-xcoff -x c++ -emit-llvm < %s 2>&1 | 
\
+// RUN: FileCheck %s
+// RUN: %clang_cc1 -triple powerpc64-ibm-aix-xcoff -x c++ -emit-llvm < %s 2>&1 
| \
+// RUN: FileCheck %s

aaron.ballman wrote:
> I think this test file should live in SemaCXX instead, as this is not testing 
> the codegen behavior, but testing the semantic checking behavior.
Actually we will support those three attributes in the future, so the warning 
are placeholders waiting for the future upgrade where we do want to check the 
codegen results. 

I agree the warnings here are confusing, I will update them with 
report_fatal_error.


Repository:
  rL LLVM

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D74166/new/

https://reviews.llvm.org/D74166



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D74166: [AIX][Frontend] Static init implementation for AIX considering no priority

2020-05-12 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L updated this revision to Diff 263499.
Xiangling_L marked 3 inline comments as done.
Xiangling_L added a comment.

Updated the warnings to `report_fatal_error`;
Update the testcases;


Repository:
  rL LLVM

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D74166/new/

https://reviews.llvm.org/D74166

Files:
  clang/include/clang/AST/Mangle.h
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/CodeGen/CGCXXABI.h
  clang/lib/CodeGen/CGDeclCXX.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/CodeGen/CodeGenModule.h
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/CodeGen/aix-constructor-attribute.cpp
  clang/test/CodeGen/aix-destructor-attribute.cpp
  clang/test/CodeGen/aix-init-priority-attribute.cpp
  clang/test/CodeGen/static-init.cpp

Index: clang/test/CodeGen/static-init.cpp
===
--- clang/test/CodeGen/static-init.cpp
+++ clang/test/CodeGen/static-init.cpp
@@ -1,12 +1,55 @@
-// RUN: not %clang_cc1 -triple powerpc-ibm-aix-xcoff -S -emit-llvm -x c++ %s \
-// RUN: -o /dev/null 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -triple powerpc-ibm-aix-xcoff -S -emit-llvm -x c++ < %s \
+// RUN: | FileCheck %s
 
-// RUN: not %clang_cc1 -triple powerpc64-ibm-aix-xcoff -S -emit-llvm -x c++ %s \
-// RUN: -o /dev/null 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -triple powerpc64-ibm-aix-xcoff -S -emit-llvm -x c++ < %s \
+// RUN: | FileCheck %s
 
 struct test {
   test();
   ~test();
 } t;
 
-// CHECK: error in backend: Static initialization has not been implemented on XL ABI yet.
+// CHECK: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @__sinit8000_clang_b2e4830f1c9d2d063e5ea946868f3bfd, i8* null }]
+// CHECK: @llvm.global_dtors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @__sterm8000_clang_b2e4830f1c9d2d063e5ea946868f3bfd, i8* null }]
+// CHECK: define dso_local void @__cxx_global_var_init() {
+// CHECK: entry:
+// CHECK:   call void @_ZN4testC1Ev(%struct.test* @t)
+// CHECK:   %0 = call i32 @atexit(void ()* @__dtor_t)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define dso_local void @__dtor_t() {
+// CHECK: entry:
+// CHECK:   call void @_ZN4testD1Ev(%struct.test* @t)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: declare i32 @atexit(void ()*)
+
+// CHECK: define dso_local void @__cxx_global_var_destruct_t() {
+// CHECK: entry:
+// CHECK:   %0 = call i32 @unatexit(void ()* @__dtor_t)
+// CHECK:   %guard.hasSrterm = icmp eq i32 %0, 0
+// CHECK:   br i1 %guard.hasSrterm, label %destruct.check, label %destruct.end
+
+// CHECK: destruct.check:
+// CHECK:   call void @__dtor_t()
+// CHECK:   br label %destruct.end
+
+// CHECK: destruct.end:
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: declare i32 @unatexit(void ()*)
+
+// CHECK: define dso_local void @__sinit8000_clang_b2e4830f1c9d2d063e5ea946868f3bfd() {
+// CHECK: entry:
+// CHECK:   call void @__cxx_global_var_init()
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define dso_local void @__sterm8000_clang_b2e4830f1c9d2d063e5ea946868f3bfd() {
+// CHECK: entry:
+// CHECK:   call void @__cxx_global_var_destruct_t()
+// CHECK:   ret void
+// CHECK: }
Index: clang/test/CodeGen/aix-init-priority-attribute.cpp
===
--- /dev/null
+++ clang/test/CodeGen/aix-init-priority-attribute.cpp
@@ -0,0 +1,16 @@
+// RUN: not %clang_cc1 -triple powerpc-ibm-aix-xcoff -x c++ -emit-llvm < %s \
+// RUN: 2>&1 | FileCheck %s
+// RUN: not %clang_cc1 -triple powerpc64-ibm-aix-xcoff -x c++ -emit-llvm < %s \
+// RUN: 2>&1 | FileCheck %s
+
+class test {
+   int a;
+public:
+test(int c) {a = c;}
+~test() {a = 0;}
+};
+
+__attribute__ ((init_priority (2000)))
+test t(1);
+
+// CHECK: fatal error: error in backend: 'init_priority' attribute unsupported on AIX yet
Index: clang/test/CodeGen/aix-destructor-attribute.cpp
===
--- /dev/null
+++ clang/test/CodeGen/aix-destructor-attribute.cpp
@@ -0,0 +1,17 @@
+// RUN: not %clang_cc1 -triple powerpc-ibm-aix-xcoff -x c++ -emit-llvm < %s \
+// RUN: 2>&1 | FileCheck %s
+// RUN: not %clang_cc1 -triple powerpc64-ibm-aix-xcoff -x c++ -emit-llvm < %s \
+// RUN: 2>&1 | FileCheck %s
+
+int bar() __attribute__((destructor(180)));
+
+class test {
+   int a;
+public:
+test(int c) {a = c;}
+~test() {a = 0;}
+};
+
+test t(1);
+
+// CHECK: fatal error: error in backend: 'destructor' attribute unsupported on AIX yet
Index: clang/test/CodeGen/aix-constructor-attribute.cpp
===
--- /dev/null
+++ clang/test/CodeGen/aix-constructor-attribute.cpp
@@ -0,0 +1,17 @@
+// RUN: not %clang_cc1 -triple powerpc-ibm-aix-xcoff -x c++ -emit-llvm < %s \
+// RUN: 2>&1 | FileCheck %s
+// RUN: not %clang_cc1 -triple powerpc64-ibm-aix-xcoff -x c++ -emit-llv

[PATCH] D79035: [clang][AIX] Implement ABIInfo and TargetCodeGenInfo for AIX

2020-05-13 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L added inline comments.



Comment at: clang/lib/Frontend/CompilerInvocation.cpp:1300
   OPT_maix_struct_return, OPT_msvr4_struct_return)) {
+// TODO: We might want to consider enabling these options on AIX in the
+// future.

Since we disable them in FE, should we remove the one in driver?



Comment at: clang/test/Frontend/aix-unsupported.c:10
+// RUN:   -c %s 2>&1 | FileCheck %s
+// CHECK: unsupported option

One thing I am not so sure about is that for these two options 
`-maix-struct-return`,  `-msvr4-struct-return`, do we need to update the 
`ClangCommandLineReference.rst` since we emit diags `unsupported option 
'-maix-struct-return' for target 'powerpc-unknown-aix'`


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D79035/new/

https://reviews.llvm.org/D79035



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D74166: [AIX][Frontend] Static init implementation for AIX considering no priority

2020-05-13 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L updated this revision to Diff 263843.
Xiangling_L added a comment.

Fix a minor issue in the testcase


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D74166/new/

https://reviews.llvm.org/D74166

Files:
  clang/include/clang/AST/Mangle.h
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/CodeGen/CGCXXABI.h
  clang/lib/CodeGen/CGDeclCXX.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/CodeGen/CodeGenModule.h
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/CodeGen/aix-constructor-attribute.cpp
  clang/test/CodeGen/aix-destructor-attribute.cpp
  clang/test/CodeGen/aix-init-priority-attribute.cpp
  clang/test/CodeGen/static-init.cpp

Index: clang/test/CodeGen/static-init.cpp
===
--- clang/test/CodeGen/static-init.cpp
+++ clang/test/CodeGen/static-init.cpp
@@ -1,12 +1,55 @@
-// RUN: not %clang_cc1 -triple powerpc-ibm-aix-xcoff -S -emit-llvm -x c++ %s \
-// RUN: -o /dev/null 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -triple powerpc-ibm-aix-xcoff -S -emit-llvm -x c++ < %s \
+// RUN: | FileCheck %s
 
-// RUN: not %clang_cc1 -triple powerpc64-ibm-aix-xcoff -S -emit-llvm -x c++ %s \
-// RUN: -o /dev/null 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -triple powerpc64-ibm-aix-xcoff -S -emit-llvm -x c++ < %s \
+// RUN: | FileCheck %s
 
 struct test {
   test();
   ~test();
 } t;
 
-// CHECK: error in backend: Static initialization has not been implemented on XL ABI yet.
+// CHECK: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @__sinit8000_clang_b2e4830f1c9d2d063e5ea946868f3bfd, i8* null }]
+// CHECK: @llvm.global_dtors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @__sterm8000_clang_b2e4830f1c9d2d063e5ea946868f3bfd, i8* null }]
+// CHECK: define dso_local void @__cxx_global_var_init() #0 {
+// CHECK: entry:
+// CHECK:   call void @_ZN4testC1Ev(%struct.test* @t)
+// CHECK:   %0 = call i32 @atexit(void ()* @__dtor_t)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define dso_local void @__dtor_t() #0 {
+// CHECK: entry:
+// CHECK:   call void @_ZN4testD1Ev(%struct.test* @t)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: declare i32 @atexit(void ()*)
+
+// CHECK: define dso_local void @__cxx_global_var_destruct_t() #0 {
+// CHECK: entry:
+// CHECK:   %0 = call i32 @unatexit(void ()* @__dtor_t)
+// CHECK:   %guard.hasSrterm = icmp eq i32 %0, 0
+// CHECK:   br i1 %guard.hasSrterm, label %destruct.check, label %destruct.end
+
+// CHECK: destruct.check:
+// CHECK:   call void @__dtor_t()
+// CHECK:   br label %destruct.end
+
+// CHECK: destruct.end:
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: declare i32 @unatexit(void ()*)
+
+// CHECK: define dso_local void @__sinit8000_clang_b2e4830f1c9d2d063e5ea946868f3bfd() #0 {
+// CHECK: entry:
+// CHECK:   call void @__cxx_global_var_init()
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define dso_local void @__sterm8000_clang_b2e4830f1c9d2d063e5ea946868f3bfd() #0 {
+// CHECK: entry:
+// CHECK:   call void @__cxx_global_var_destruct_t()
+// CHECK:   ret void
+// CHECK: }
Index: clang/test/CodeGen/aix-init-priority-attribute.cpp
===
--- /dev/null
+++ clang/test/CodeGen/aix-init-priority-attribute.cpp
@@ -0,0 +1,16 @@
+// RUN: not %clang_cc1 -triple powerpc-ibm-aix-xcoff -x c++ -emit-llvm < %s \
+// RUN: 2>&1 | FileCheck %s
+// RUN: not %clang_cc1 -triple powerpc64-ibm-aix-xcoff -x c++ -emit-llvm < %s \
+// RUN: 2>&1 | FileCheck %s
+
+class test {
+   int a;
+public:
+test(int c) {a = c;}
+~test() {a = 0;}
+};
+
+__attribute__ ((init_priority (2000)))
+test t(1);
+
+// CHECK: fatal error: error in backend: 'init_priority' attribute unsupported on AIX yet
Index: clang/test/CodeGen/aix-destructor-attribute.cpp
===
--- /dev/null
+++ clang/test/CodeGen/aix-destructor-attribute.cpp
@@ -0,0 +1,17 @@
+// RUN: not %clang_cc1 -triple powerpc-ibm-aix-xcoff -x c++ -emit-llvm < %s \
+// RUN: 2>&1 | FileCheck %s
+// RUN: not %clang_cc1 -triple powerpc64-ibm-aix-xcoff -x c++ -emit-llvm < %s \
+// RUN: 2>&1 | FileCheck %s
+
+int bar() __attribute__((destructor(180)));
+
+class test {
+   int a;
+public:
+test(int c) {a = c;}
+~test() {a = 0;}
+};
+
+test t(1);
+
+// CHECK: fatal error: error in backend: 'destructor' attribute unsupported on AIX yet
Index: clang/test/CodeGen/aix-constructor-attribute.cpp
===
--- /dev/null
+++ clang/test/CodeGen/aix-constructor-attribute.cpp
@@ -0,0 +1,17 @@
+// RUN: not %clang_cc1 -triple powerpc-ibm-aix-xcoff -x c++ -emit-llvm < %s \
+// RUN: 2>&1 | FileCheck %s
+// RUN: not %clang_cc1 -triple powerpc64-ibm-aix-xcoff -x c++ -emit-llvm < %s \
+// RUN: 2>&1 | FileCheck %s
+
+int foo(

[PATCH] D74166: [AIX][Frontend] Static init implementation for AIX considering no priority

2020-05-14 Thread Xiangling Liao via Phabricator via cfe-commits
Xiangling_L updated this revision to Diff 264009.
Xiangling_L added a comment.

Clean `clang-tidy` warnings and `clang-format` errors


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D74166/new/

https://reviews.llvm.org/D74166

Files:
  clang/include/clang/AST/Mangle.h
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/CodeGen/CGCXXABI.h
  clang/lib/CodeGen/CGDeclCXX.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/CodeGen/CodeGenModule.h
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/CodeGen/aix-constructor-attribute.cpp
  clang/test/CodeGen/aix-destructor-attribute.cpp
  clang/test/CodeGen/aix-init-priority-attribute.cpp
  clang/test/CodeGen/static-init.cpp

Index: clang/test/CodeGen/static-init.cpp
===
--- clang/test/CodeGen/static-init.cpp
+++ clang/test/CodeGen/static-init.cpp
@@ -1,12 +1,55 @@
-// RUN: not %clang_cc1 -triple powerpc-ibm-aix-xcoff -S -emit-llvm -x c++ %s \
-// RUN: -o /dev/null 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -triple powerpc-ibm-aix-xcoff -S -emit-llvm -x c++ < %s \
+// RUN: | FileCheck %s
 
-// RUN: not %clang_cc1 -triple powerpc64-ibm-aix-xcoff -S -emit-llvm -x c++ %s \
-// RUN: -o /dev/null 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -triple powerpc64-ibm-aix-xcoff -S -emit-llvm -x c++ < %s \
+// RUN: | FileCheck %s
 
 struct test {
   test();
   ~test();
 } t;
 
-// CHECK: error in backend: Static initialization has not been implemented on XL ABI yet.
+// CHECK: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @__sinit8000_clang_b2e4830f1c9d2d063e5ea946868f3bfd, i8* null }]
+// CHECK: @llvm.global_dtors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @__sterm8000_clang_b2e4830f1c9d2d063e5ea946868f3bfd, i8* null }]
+// CHECK: define dso_local void @__cxx_global_var_init() #0 {
+// CHECK: entry:
+// CHECK:   call void @_ZN4testC1Ev(%struct.test* @t)
+// CHECK:   %0 = call i32 @atexit(void ()* @__dtor_t)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define dso_local void @__dtor_t() #0 {
+// CHECK: entry:
+// CHECK:   call void @_ZN4testD1Ev(%struct.test* @t)
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: declare i32 @atexit(void ()*)
+
+// CHECK: define dso_local void @__cxx_global_var_destruct_t() #0 {
+// CHECK: entry:
+// CHECK:   %0 = call i32 @unatexit(void ()* @__dtor_t)
+// CHECK:   %guard.hasSrterm = icmp eq i32 %0, 0
+// CHECK:   br i1 %guard.hasSrterm, label %destruct.check, label %destruct.end
+
+// CHECK: destruct.check:
+// CHECK:   call void @__dtor_t()
+// CHECK:   br label %destruct.end
+
+// CHECK: destruct.end:
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: declare i32 @unatexit(void ()*)
+
+// CHECK: define dso_local void @__sinit8000_clang_b2e4830f1c9d2d063e5ea946868f3bfd() #0 {
+// CHECK: entry:
+// CHECK:   call void @__cxx_global_var_init()
+// CHECK:   ret void
+// CHECK: }
+
+// CHECK: define dso_local void @__sterm8000_clang_b2e4830f1c9d2d063e5ea946868f3bfd() #0 {
+// CHECK: entry:
+// CHECK:   call void @__cxx_global_var_destruct_t()
+// CHECK:   ret void
+// CHECK: }
Index: clang/test/CodeGen/aix-init-priority-attribute.cpp
===
--- /dev/null
+++ clang/test/CodeGen/aix-init-priority-attribute.cpp
@@ -0,0 +1,16 @@
+// RUN: not %clang_cc1 -triple powerpc-ibm-aix-xcoff -x c++ -emit-llvm < %s \
+// RUN: 2>&1 | FileCheck %s
+// RUN: not %clang_cc1 -triple powerpc64-ibm-aix-xcoff -x c++ -emit-llvm < %s \
+// RUN: 2>&1 | FileCheck %s
+
+class test {
+  int a;
+public:
+  test(int c) {a = c;}
+  ~test() {a = 0;}
+};
+
+__attribute__((init_priority(2000)))
+test t(1);
+
+// CHECK: fatal error: error in backend: 'init_priority' attribute unsupported on AIX yet
Index: clang/test/CodeGen/aix-destructor-attribute.cpp
===
--- /dev/null
+++ clang/test/CodeGen/aix-destructor-attribute.cpp
@@ -0,0 +1,17 @@
+// RUN: not %clang_cc1 -triple powerpc-ibm-aix-xcoff -x c++ -emit-llvm < %s \
+// RUN: 2>&1 | FileCheck %s
+// RUN: not %clang_cc1 -triple powerpc64-ibm-aix-xcoff -x c++ -emit-llvm < %s \
+// RUN: 2>&1 | FileCheck %s
+
+int bar() __attribute__((destructor(180)));
+
+class test {
+  int a;
+public:
+  test(int c) {a = c;}
+  ~test() {a = 0;}
+};
+
+test t(1);
+
+// CHECK: fatal error: error in backend: 'destructor' attribute unsupported on AIX yet
Index: clang/test/CodeGen/aix-constructor-attribute.cpp
===
--- /dev/null
+++ clang/test/CodeGen/aix-constructor-attribute.cpp
@@ -0,0 +1,17 @@
+// RUN: not %clang_cc1 -triple powerpc-ibm-aix-xcoff -x c++ -emit-llvm < %s \
+// RUN: 2>&1 | FileCheck %s
+// RUN: not %clang_cc1 -triple powerpc64-ibm-aix-xcoff -x c++ -emit-llvm < %s \
+// RUN: 2>&1 | FileCheck %s
+
+

  1   2   3   >