[llvm-branch-commits] [libcxx] 55e34f3 - [libc++] Always enable the ranges concepts
Author: Nikolas Klauser Date: 2022-05-24T09:09:31-04:00 New Revision: 55e34f3b49b1485d57ba2e4b8cd88af8f7900f61 URL: https://github.com/llvm/llvm-project/commit/55e34f3b49b1485d57ba2e4b8cd88af8f7900f61 DIFF: https://github.com/llvm/llvm-project/commit/55e34f3b49b1485d57ba2e4b8cd88af8f7900f61.diff LOG: [libc++] Always enable the ranges concepts The ranges concepts were already available in libc++13, so we shouldn't guard them with `_LIBCPP_HAS_NO_INCOMPLETE_RANGES`. Fixes https://github.com/llvm/llvm-project/issues/54765 Differential Revision: https://reviews.llvm.org/D124011 (cherry picked from commit b177a90ce7b590dfce6479142f46fd1b9554a3b3) Added: Modified: libcxx/include/__ranges/concepts.h libcxx/include/__ranges/data.h libcxx/include/__ranges/size.h libcxx/test/libcxx/ranges/has-no-incomplete-ranges.compile.pass.cpp libcxx/test/std/ranges/range.access/data.pass.cpp libcxx/test/std/ranges/range.access/size.pass.cpp libcxx/test/std/ranges/range.req/range.refinements/common_range.compile.pass.cpp libcxx/test/std/ranges/range.req/range.refinements/subsumption.compile.pass.cpp Removed: diff --git a/libcxx/include/__ranges/concepts.h b/libcxx/include/__ranges/concepts.h index 5f1fa834d4099..e16343591cdac 100644 --- a/libcxx/include/__ranges/concepts.h +++ b/libcxx/include/__ranges/concepts.h @@ -68,8 +68,6 @@ namespace ranges { template using range_rvalue_reference_t = iter_rvalue_reference_t>; -#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - // [range.sized] template concept sized_range = range<_Tp> && requires(_Tp& __t) { ranges::size(__t); }; @@ -135,8 +133,6 @@ namespace ranges { (is_lvalue_reference_v<_Tp> || (movable> && !__is_std_initializer_list>; -#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) - } // namespace ranges #endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) diff --git a/libcxx/include/__ranges/data.h b/libcxx/include/__ranges/data.h index f8d92cbc75204..f97ec80332976 100644 --- a/libcxx/include/__ranges/data.h +++ b/libcxx/include/__ranges/data.h @@ -24,7 +24,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) // [range.prim.data] @@ -99,7 +99,7 @@ inline namespace __cpo { } // namespace __cpo } // namespace ranges -#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__ranges/size.h b/libcxx/include/__ranges/size.h index 2b71c03fb3996..e1aaf7eba898e 100644 --- a/libcxx/include/__ranges/size.h +++ b/libcxx/include/__ranges/size.h @@ -24,7 +24,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD -#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) namespace ranges { template @@ -128,7 +128,7 @@ inline namespace __cpo { } // namespace __cpo } // namespace ranges -#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES) +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/test/libcxx/ranges/has-no-incomplete-ranges.compile.pass.cpp b/libcxx/test/libcxx/ranges/has-no-incomplete-ranges.compile.pass.cpp index 0d151073ca481..3dd6b20cc3733 100644 --- a/libcxx/test/libcxx/ranges/has-no-incomplete-ranges.compile.pass.cpp +++ b/libcxx/test/libcxx/ranges/has-no-incomplete-ranges.compile.pass.cpp @@ -25,7 +25,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { - int output_range; int data; int size; int prev; @@ -37,5 +36,5 @@ namespace ranges { int filter_view; int join_view; int views; // this entire namespace should be absent -} +} // namespace ranges _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/test/std/ranges/range.access/data.pass.cpp b/libcxx/test/std/ranges/range.access/data.pass.cpp index d7d87e2eb0415..3e26ea28b2a6e 100644 --- a/libcxx/test/std/ranges/range.access/data.pass.cpp +++ b/libcxx/test/std/ranges/range.access/data.pass.cpp @@ -8,7 +8,6 @@ // UNSUPPORTED: c++03, c++11, c++14, c++17 // UNSUPPORTED: libcpp-no-concepts -// UNSUPPORTED: libcpp-has-no-incomplete-ranges // std::ranges::data diff --git a/libcxx/test/std/ranges/range.access/size.pass.cpp b/libcxx/test/std/ranges/range.access/size.pass.cpp index 2cfa2ad37dfbe..40eb413a6d6a0 100644 --- a/libcxx/test/std/ranges/range.access/size.pass.cpp +++ b/libcxx/test/std/ranges/range.access/size.pass.cpp @@ -8,7 +8,6 @@ // UNSUPPORTED: c++03, c++11, c++14, c++17 // UNSUPPORTED: libcpp-no-concepts -// UNSUPPORTED: libcpp-has-no-incomplete-ranges // std::ranges::size diff --git a/libcxx/test/std/ranges/range.req/range.refinements/common_range.compile.pass.cpp b/libcxx/test/std/ranges/range.req/ra
[llvm-branch-commits] [libcxx] f45a01e - [libc++][CI] added XFAIL LIBCXX-AIX-FIXME to new runnning test cases after install locale fileset on AIX OS.
Author: zhijian Date: 2022-05-24T09:13:47-04:00 New Revision: f45a01e4a170385625d2a46f3b770b0f73a1af85 URL: https://github.com/llvm/llvm-project/commit/f45a01e4a170385625d2a46f3b770b0f73a1af85 DIFF: https://github.com/llvm/llvm-project/commit/f45a01e4a170385625d2a46f3b770b0f73a1af85.diff LOG: [libc++][CI] added XFAIL LIBCXX-AIX-FIXME to new runnning test cases after install locale fileset on AIX OS. Summary: 1. there are 23 test cases which do not run because of locale fileset not install, after the locale installed, these test cases will be run and fail. "LIBCXX-AIX-FIXME" on the 23 test cases which remain to be investigated on AIX. 2.after installed the locale fileset , the test case libcxx/test/std/localization/locale.categories/category.collate/locale.collate.byname/compare.pass.cpp pass remove XFAIL: LIBCXX-AIX-FIXME from the file Reviewers: David Tenty Differential Revision: https://reviews.llvm.org/D124174 (cherry picked from commit bf4ddf18406c3e523c798ff7809f9e647580588c) Added: Modified: libcxx/test/std/localization/locale.categories/category.collate/locale.collate.byname/compare.pass.cpp libcxx/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_ru_RU.pass.cpp libcxx/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_ru_RU.pass.cpp libcxx/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/curr_symbol.pass.cpp libcxx/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/grouping.pass.cpp libcxx/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/neg_format.pass.cpp libcxx/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/pos_format.pass.cpp libcxx/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/thousands_sep.pass.cpp libcxx/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_date.pass.cpp libcxx/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_date_wide.pass.cpp libcxx/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_one.pass.cpp libcxx/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_one_wide.pass.cpp libcxx/test/std/localization/locale.categories/category.time/locale.time.put.byname/put1.pass.cpp libcxx/test/std/re/re.alg/re.alg.match/awk.locale.pass.cpp libcxx/test/std/re/re.alg/re.alg.match/basic.locale.pass.cpp libcxx/test/std/re/re.alg/re.alg.match/ecma.locale.pass.cpp libcxx/test/std/re/re.alg/re.alg.match/extended.locale.pass.cpp libcxx/test/std/re/re.alg/re.alg.search/awk.locale.pass.cpp libcxx/test/std/re/re.alg/re.alg.search/basic.locale.pass.cpp libcxx/test/std/re/re.alg/re.alg.search/ecma.locale.pass.cpp libcxx/test/std/re/re.alg/re.alg.search/extended.locale.pass.cpp libcxx/test/std/re/re.traits/lookup_collatename.pass.cpp libcxx/test/std/re/re.traits/transform.pass.cpp libcxx/test/std/re/re.traits/transform_primary.pass.cpp Removed: diff --git a/libcxx/test/std/localization/locale.categories/category.collate/locale.collate.byname/compare.pass.cpp b/libcxx/test/std/localization/locale.categories/category.collate/locale.collate.byname/compare.pass.cpp index 5a8305608e1e1..65baa2a01fc87 100644 --- a/libcxx/test/std/localization/locale.categories/category.collate/locale.collate.byname/compare.pass.cpp +++ b/libcxx/test/std/localization/locale.categories/category.collate/locale.collate.byname/compare.pass.cpp @@ -25,8 +25,6 @@ // XFAIL: LIBCXX-WINDOWS-FIXME -// XFAIL: LIBCXX-AIX-FIXME - #include #include #include diff --git a/libcxx/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_ru_RU.pass.cpp b/libcxx/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_ru_RU.pass.cpp index ff33764d2683b..d6aa5331a0664 100644 --- a/libcxx/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_ru_RU.pass.cpp +++ b/libcxx/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_ru_RU.pass.cpp @@ -18,6 +18,7 @@ // XFAIL: LIBCXX-WINDOWS-FIXME // REQUIRES: locale.ru_RU.UTF-8 +// XFAIL: LIBCXX-AIX-FIXME // diff --git a/libcxx/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_ru_RU.pass.cpp b/libcxx/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_ru_RU.pass.cpp index 8
[llvm-branch-commits] [llvm] 42fe7cc - [SystemZ] Bugfix for symbolic displacements.
Author: Jonas Paulsson Date: 2022-05-24T10:43:28-07:00 New Revision: 42fe7ccbeb444d1e22eac36035758dc17c4aa9c5 URL: https://github.com/llvm/llvm-project/commit/42fe7ccbeb444d1e22eac36035758dc17c4aa9c5 DIFF: https://github.com/llvm/llvm-project/commit/42fe7ccbeb444d1e22eac36035758dc17c4aa9c5.diff LOG: [SystemZ] Bugfix for symbolic displacements. Properly handle the case where only the second operand of e.g. an MVC instruction uses a fixup for the displacement. Reviewed By: Ulrich Weigand Differential Revision: https://reviews.llvm.org/D125982 (cherry picked from commit e547b04d5b2c20bb5d14e49a86837c77573b267a) Added: Modified: llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp llvm/test/MC/SystemZ/fixups.s Removed: diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp index c83796b8579b9..9eb546d1b5dc6 100644 --- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp +++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp @@ -37,6 +37,8 @@ class SystemZMCCodeEmitter : public MCCodeEmitter { const MCInstrInfo &MCII; MCContext &Ctx; + mutable unsigned MemOpsEmitted; + public: SystemZMCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx) : MCII(mcii), Ctx(ctx) { @@ -165,6 +167,7 @@ encodeInstruction(const MCInst &MI, raw_ostream &OS, verifyInstructionPredicates(MI, computeAvailableFeatures(STI.getFeatureBits())); + MemOpsEmitted = 0; uint64_t Bits = getBinaryCodeForInstr(MI, Fixups, STI); unsigned Size = MCII.get(MI.getOpcode()).getSize(); // Big-endian insertion of Size bytes. @@ -191,12 +194,14 @@ getDispOpValue(const MCInst &MI, unsigned OpNum, SmallVectorImpl &Fixups, SystemZ::FixupKind Kind) const { const MCOperand &MO = MI.getOperand(OpNum); - if (MO.isImm()) + if (MO.isImm()) { +++MemOpsEmitted; return static_cast(MO.getImm()); + } if (MO.isExpr()) { // All instructions follow the pattern where the first displacement has a // 2 bytes offset, and the second one 4 bytes. -unsigned ByteOffs = Fixups.size() == 0 ? 2 : 4; +unsigned ByteOffs = MemOpsEmitted++ == 0 ? 2 : 4; Fixups.push_back(MCFixup::create(ByteOffs, MO.getExpr(), (MCFixupKind)Kind, MI.getLoc())); assert(Fixups.size() <= 2 && "More than two memory operands in MI?"); diff --git a/llvm/test/MC/SystemZ/fixups.s b/llvm/test/MC/SystemZ/fixups.s index 25202bb82c1c5..77c71e3c987b1 100644 --- a/llvm/test/MC/SystemZ/fixups.s +++ b/llvm/test/MC/SystemZ/fixups.s @@ -287,6 +287,11 @@ .align 16 vgeg %v0, src(%v0,%r1), 0 +## Fixup for second operand only +# CHECK: mvc 32(8,%r0), src# encoding: [0xd2,0x07,0x00,0x20,0b,A] +# CHECK-NEXT: # fixup A - offset: 4, value: src, kind: FK_390_12 +.align 16 +mvc 32(8,%r0),src # Data relocs # llvm-mc does not show any "encoding" string for data, so we just check the relocs ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] c81f3d0 - [AVR] Generate 'rcall' instead of 'call' on avr2 and avr25
Author: Ben Shi Date: 2022-05-24T10:53:49-07:00 New Revision: c81f3d00cbd4f1e6771512f837440d1676fb55ae URL: https://github.com/llvm/llvm-project/commit/c81f3d00cbd4f1e6771512f837440d1676fb55ae DIFF: https://github.com/llvm/llvm-project/commit/c81f3d00cbd4f1e6771512f837440d1676fb55ae.diff LOG: [AVR] Generate 'rcall' instead of 'call' on avr2 and avr25 The 'call' (long call) instruction is available on avr3 and above, and devices in avr2 and avr25 should use the 'rcall' (short call) instruction for function calls. Reviewed By: aykevl, dylanmckay Differential Revision: https://reviews.llvm.org/D121539 (cherry picked from commit 45638931fb7c7a1b9c850e47601541b398868538) Added: Modified: llvm/lib/Target/AVR/AVRInstrInfo.td llvm/test/CodeGen/AVR/call.ll Removed: diff --git a/llvm/lib/Target/AVR/AVRInstrInfo.td b/llvm/lib/Target/AVR/AVRInstrInfo.td index 2b96dc0b833ad..7e027369f096f 100644 --- a/llvm/lib/Target/AVR/AVRInstrInfo.td +++ b/llvm/lib/Target/AVR/AVRInstrInfo.td @@ -194,6 +194,11 @@ def brtarget_13 : Operand { let EncoderMethod = "encodeRelCondBrTarget"; } +def rcalltarget_13 : Operand { + let PrintMethod = "printPCRelImm"; + let EncoderMethod = "encodeRelCondBrTarget"; +} + // The target of a 22 or 16-bit call/jmp instruction. def call_target : Operand { let EncoderMethod = "encodeCallTarget"; @@ -965,10 +970,8 @@ let isBarrier = 1, isBranch = 1, isTerminator = 1 in { let isCall = 1 in { // SP is marked as a use to prevent stack-pointer assignments that appear // immediately before calls from potentially appearing dead. - let Uses = [SP] in def RCALLk : FBRk<1, (outs), - (ins brtarget_13 -: $target), - "rcall\t$target", []>; + let Uses = [SP] in def RCALLk : FBRk<1, (outs), (ins rcalltarget_13:$k), + "rcall\t$k", [(AVRcall imm:$k)]>; // SP is marked as a use to prevent stack-pointer assignments that appear // immediately before calls from potentially appearing dead. @@ -985,13 +988,10 @@ let isCall = 1 in { // SP is marked as a use to prevent stack-pointer assignments that appear // immediately before calls from potentially appearing dead. // - //: TODO: the imm field can be either 16 or 22 bits in devices with more + // TODO: the imm field can be either 16 or 22 bits in devices with more // than 64k of ROM, fix it once we support the largest devices. - let Uses = [SP] in def CALLk : F32BRk<0b111, (outs), -(ins call_target - : $k), -"call\t$k", [(AVRcall imm - : $k)]>, + let Uses = [SP] in def CALLk : F32BRk<0b111, (outs), (ins call_target:$k), +"call\t$k", [(AVRcall imm:$k)]>, Requires<[HasJMPCALL]>; } @@ -2457,8 +2457,12 @@ def : Pat<(adde i8 : $src2))>; // Calls. -def : Pat<(AVRcall(i16 tglobaladdr : $dst)), (CALLk tglobaladdr : $dst)>; -def : Pat<(AVRcall(i16 texternalsym : $dst)), (CALLk texternalsym : $dst)>; +let Predicates = [HasJMPCALL] in { + def : Pat<(AVRcall(i16 tglobaladdr:$dst)), (CALLk tglobaladdr:$dst)>; + def : Pat<(AVRcall(i16 texternalsym:$dst)), (CALLk texternalsym:$dst)>; +} +def : Pat<(AVRcall(i16 tglobaladdr:$dst)), (RCALLk tglobaladdr:$dst)>; +def : Pat<(AVRcall(i16 texternalsym:$dst)), (RCALLk texternalsym:$dst)>; // `anyext` def : Pat<(i16(anyext i8 diff --git a/llvm/test/CodeGen/AVR/call.ll b/llvm/test/CodeGen/AVR/call.ll index 7d94f9b488789..ec91480163b1e 100644 --- a/llvm/test/CodeGen/AVR/call.ll +++ b/llvm/test/CodeGen/AVR/call.ll @@ -1,4 +1,5 @@ -; RUN: llc < %s -march=avr -mattr=avr6 | FileCheck %s +; RUN: llc < %s -mtriple=avr -mcpu=avr6 | FileCheck %s --check-prefixes=CHECK,AVR6 +; RUN: llc < %s -mtriple=avr -mcpu=avr2 | FileCheck %s --check-prefixes=CHECK,AVR2 ; TODO: test returning byval structs @@ -18,11 +19,13 @@ declare i64 @foo64_2(i64, i64, i64) define i8 @calli8_reg() { ; CHECK-LABEL: calli8_reg: ; CHECK: ldi r24, 12 -; CHECK: call foo8_1 +; AVR6: call foo8_1 +; AVR2: rcall foo8_1 ; CHECK: ldi r24, 12 ; CHECK: ldi r22, 13 ; CHECK: ldi r20, 14 -; CHECK: call foo8_2 +; AVR6: call foo8_2 +; AVR2: rcall foo8_2 %result1 = call i8 @foo8_1(i8 12) %result2 = call i8 @foo8_2(i8 12, i8 13, i8 14) ret i8 %result2 @@ -34,7 +37,8 @@ define i8 @calli8_stack() { ; CHECK: ldi [[REG2:r[0-9]+]], 11 ; CHECK: std Z+1, [[REG1]] ; CHECK: std Z+2, [[REG2]] -; CHECK: call foo8_3 +; AVR6: call foo8_3 +; AVR2: rcall foo8_3 %result1 = call i8 @foo8_3(i8 1, i8 2, i8 3, i8 4, i8 5, i8 6, i8 7, i8 8, i8 9, i8 10, i8 11) ret i8 %result1 } @@ -45,7 +49,8 @@ define i16 @calli16_reg
[llvm-branch-commits] [llvm] 5f6fe6b - [AVR] Fix incorrect calling convention for varargs functions
Author: Ben Shi Date: 2022-05-24T10:53:49-07:00 New Revision: 5f6fe6b93e85aa90b92681037f4dd42403368bb4 URL: https://github.com/llvm/llvm-project/commit/5f6fe6b93e85aa90b92681037f4dd42403368bb4 DIFF: https://github.com/llvm/llvm-project/commit/5f6fe6b93e85aa90b92681037f4dd42403368bb4.diff LOG: [AVR] Fix incorrect calling convention for varargs functions An i8 argument should only cost 1 byte on the stack. This is compatible with avr-gcc. There are also more test cases (of calling convention) are added. Reviewed By: aykevl, dylanmckay Differential Revision: https://reviews.llvm.org/D121767 (cherry picked from commit 3fd9a320da8adbefa47071f70667d641f7dd26f2) Added: Modified: llvm/lib/Target/AVR/AVRCallingConv.td llvm/test/CodeGen/AVR/calling-conv/c/basic.ll llvm/test/CodeGen/AVR/calling-conv/c/basic_aggr.ll llvm/test/CodeGen/AVR/calling-conv/c/stack.ll Removed: diff --git a/llvm/lib/Target/AVR/AVRCallingConv.td b/llvm/lib/Target/AVR/AVRCallingConv.td index b4bc35e191c01..0fae61fb55c5f 100644 --- a/llvm/lib/Target/AVR/AVRCallingConv.td +++ b/llvm/lib/Target/AVR/AVRCallingConv.td @@ -27,6 +27,8 @@ def RetCC_AVR_BUILTIN : CallingConv<[ // Calling convention for variadic functions. def ArgCC_AVR_Vararg : CallingConv<[ + // i8 are always passed through the stack with a byte slot and byte alignment. + CCIfType<[i8], CCAssignToStack<1, 1>>, // i16 are always passed through the stack with an alignment of 1. CCAssignToStack<2, 1> ]>; diff --git a/llvm/test/CodeGen/AVR/calling-conv/c/basic.ll b/llvm/test/CodeGen/AVR/calling-conv/c/basic.ll index 80a61a47cb215..1c3c0312b0883 100644 --- a/llvm/test/CodeGen/AVR/calling-conv/c/basic.ll +++ b/llvm/test/CodeGen/AVR/calling-conv/c/basic.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=avr | FileCheck %s +; RUN: llc -mtriple=avr < %s | FileCheck %s ; CHECK-LABEL: ret_void_args_i8 define void @ret_void_args_i8(i8 %a) { @@ -97,3 +97,75 @@ define void @ret_void_args_i64_i64_i16(i64 %a, i64 %b, i16 %c) { store volatile i16 %c, i16* inttoptr (i64 4 to i16*) ret void } + +; NOTE: Both %a (i8) and %b (i8) cost two registers. +define i8 @foo0(i8 %a, i8 %b) { +; CHECK-LABEL: foo0: +; CHECK: ; %bb.0: +; CHECK-NEXT:sub r24, r22 +; CHECK-NEXT:ret + %c = sub i8 %a, %b + ret i8 %c +} + +; NOTE: Both %a (i16) and %b (i16) cost two registers. +define i16 @foo1(i16 %a, i16 %b) { +; CHECK-LABEL: foo1: +; CHECK: ; %bb.0: +; CHECK-NEXT:sub r24, r22 +; CHECK-NEXT:sbc r25, r23 +; CHECK-NEXT:ret + %c = sub i16 %a, %b + ret i16 %c +} + +; NOTE: Both %a (i32) and %b (i32) cost four registers. +define i32 @foo2(i32 %a, i32 %b) { +; CHECK-LABEL: foo2: +; CHECK: ; %bb.0: +; CHECK-NEXT:sub r22, r18 +; CHECK-NEXT:sbc r23, r19 +; CHECK-NEXT:sbc r24, r20 +; CHECK-NEXT:sbc r25, r21 +; CHECK-NEXT:ret + %c = sub i32 %a, %b + ret i32 %c +} + +; NOTE: Each argument costs four registers, and total 16 registers are used. +define i32 @foo3(i32 %a, i32 %b, i32 %c, i32 %d) { +; CHECK-LABEL: foo3: +; CHECK: ; %bb.0: +; CHECK-NEXT:sub r22, r10 +; CHECK-NEXT:sbc r23, r11 +; CHECK-NEXT:sbc r24, r12 +; CHECK-NEXT:sbc r25, r13 +; CHECK-NEXT:ret + %e = sub nsw i32 %a, %d + ret i32 %e +} + +; NOTE: Each argument (except %e) cost four registers, and total 16 registers +; NOTE: are used. Though there are still 2 registers are vacant, the %e has +; NOTE: to be dropped to the stack. +define i32 @foo4(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e) { +; CHECK-LABEL: foo4: +; CHECK: ; %bb.0: +; CHECK-NEXT:push r28 +; CHECK-NEXT:push r29 +; CHECK-NEXT:in r28, 61 +; CHECK-NEXT:in r29, 62 +; CHECK-NEXT:ldd r18, Y+5 +; CHECK-NEXT:ldd r19, Y+6 +; CHECK-NEXT:ldd r20, Y+7 +; CHECK-NEXT:ldd r21, Y+8 +; CHECK-NEXT:sub r22, r18 +; CHECK-NEXT:sbc r23, r19 +; CHECK-NEXT:sbc r24, r20 +; CHECK-NEXT:sbc r25, r21 +; CHECK-NEXT:pop r29 +; CHECK-NEXT:pop r28 +; CHECK-NEXT:ret + %f = sub nsw i32 %a, %e + ret i32 %f +} diff --git a/llvm/test/CodeGen/AVR/calling-conv/c/basic_aggr.ll b/llvm/test/CodeGen/AVR/calling-conv/c/basic_aggr.ll index 0f6cf0ed73d08..98317518057ac 100644 --- a/llvm/test/CodeGen/AVR/calling-conv/c/basic_aggr.ll +++ b/llvm/test/CodeGen/AVR/calling-conv/c/basic_aggr.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=avr | FileCheck %s +; RUN: llc -mtriple=avr < %s | FileCheck %s ; CHECK-LABEL: ret_void_args_struct_i8_i32 define void @ret_void_args_struct_i8_i32({ i8, i32 } %a) { @@ -82,3 +82,94 @@ start: ret void } +; NOTE: The %0 (8-byte array) costs 8 registers and %1 (10-byte array) +; NOTE: costs 10 registers. +define i8 @foo0([8 x i8] %0, [10 x i8] %1) { +; CHECK-LABEL: foo0: +; CHECK: ; %bb.0: +; CHECK-NEXT:sub r18, r8 +; CHECK-NEXT:mov r24, r18 +; CHECK-NEXT:ret + %3 = extractvalue [8 x i8] %0, 0 + %4 = ex
[llvm-branch-commits] [clang] 53eaee6 - [clang][NFC] Standard substitution checking cleanup
Author: Nathan Sidwell Date: 2022-05-24T10:53:49-07:00 New Revision: 53eaee6bf3b3dd49b3f0bc34385c29b03b4905da URL: https://github.com/llvm/llvm-project/commit/53eaee6bf3b3dd49b3f0bc34385c29b03b4905da DIFF: https://github.com/llvm/llvm-project/commit/53eaee6bf3b3dd49b3f0bc34385c29b03b4905da.diff LOG: [clang][NFC] Standard substitution checking cleanup In preparing for module mangling changes I noticed some issues with the way we check for std::basic_string instantiations and friends. *) there's a single routine for std::basic_{i,o,io}stream but it is templatized on the length of the name. Really? just use a StringRef, rather than clone the entire routine just for 'basic_iostream'. *) We have a helper routine to check for char type, and call it from several places. But given all the instantiations are of the form TPL ...> we could just check the first arg is char and the later templated args are instantiating that same type. A simpler type comparison. *) Because basic_string has a third allocator parameter, it is open coded, which I found a little confusing. But otherwise it's exactly the same pattern as the iostream ones. Just tell that checker about whether there's an expected allocator argument.[*] *) We may as well return in each block of mangleStandardSubstitution once we determine it is not one of the entities of interest -- it certainly cannot be one of the other kinds of entities. FWIW this shaves about 500 bytes off the executable. [*] I suppose we could also have this routine a tri-value, with one to indicat 'it is this name, but it's not the one you're looking for', to avoid later calls trying different names? Reviewd By: ChuanqiXu Differential Revision: https://reviews.llvm.org/D119333 Added: Modified: clang/lib/AST/ItaniumMangle.cpp Removed: diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 2e734e2b28cdb..b15669d426bd6 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -5969,27 +5969,19 @@ bool CXXNameMangler::mangleSubstitution(uintptr_t Ptr) { return true; } -static bool isCharType(QualType T) { - if (T.isNull()) +/// Returns whether S is a template specialization of std::Name with a single +/// argument of type A. +static bool isSpecializedAs(QualType S, llvm::StringRef Name, QualType A) { + if (S.isNull()) return false; - return T->isSpecificBuiltinType(BuiltinType::Char_S) || -T->isSpecificBuiltinType(BuiltinType::Char_U); -} - -/// Returns whether a given type is a template specialization of a given name -/// with a single argument of type char. -static bool isCharSpecialization(QualType T, const char *Name) { - if (T.isNull()) -return false; - - const RecordType *RT = T->getAs(); + const RecordType *RT = S->getAs(); if (!RT) return false; const ClassTemplateSpecializationDecl *SD = dyn_cast(RT->getDecl()); - if (!SD) + if (!SD || !SD->getIdentifier()->isStr(Name)) return false; if (!isStdNamespace(getEffectiveDeclContext(SD))) @@ -5999,26 +5991,37 @@ static bool isCharSpecialization(QualType T, const char *Name) { if (TemplateArgs.size() != 1) return false; - if (!isCharType(TemplateArgs[0].getAsType())) + if (TemplateArgs[0].getAsType() != A) return false; - return SD->getIdentifier()->getName() == Name; + return true; } -template -static bool isStreamCharSpecialization(const ClassTemplateSpecializationDecl*SD, - const char (&Str)[StrLen]) { - if (!SD->getIdentifier()->isStr(Str)) +/// Returns whether SD is a template specialization std::Name [, std::allocator]> +/// HasAllocator controls whether the 3rd template argument is needed. +static bool isStdCharSpecialization(const ClassTemplateSpecializationDecl *SD, +llvm::StringRef Name, bool HasAllocator) { + if (!SD->getIdentifier()->isStr(Name)) return false; const TemplateArgumentList &TemplateArgs = SD->getTemplateArgs(); - if (TemplateArgs.size() != 2) + if (TemplateArgs.size() != (HasAllocator ? 3 : 2)) return false; - if (!isCharType(TemplateArgs[0].getAsType())) + QualType A = TemplateArgs[0].getAsType(); + if (A.isNull()) +return false; + // Plain 'char' is named Char_S or Char_U depending on the target ABI. + if (!A->isSpecificBuiltinType(BuiltinType::Char_S) && + !A->isSpecificBuiltinType(BuiltinType::Char_U)) return false; - if (!isCharSpecialization(TemplateArgs[1].getAsType(), "char_traits")) + if (!isSpecializedAs(TemplateArgs[1].getAsType(), "char_traits", A)) +return false; + + if (HasAllocator && + !isSpecializedAs(TemplateArgs[2].getAsType(), "allocator", A)) return false; return true; @@ -6031,6 +6034,7 @@ bool CXXNameMangler::mangleStandardSubstitution(const NamedDecl *ND) { Out << "St";
[llvm-branch-commits] [clang] 0009cdb - [clang][NFC] Remove IgnoreLinkageSpecDecls
Author: Nathan Sidwell Date: 2022-05-24T10:53:49-07:00 New Revision: 0009cdbd8a3ab27b1edefa0e9a6fdf41d66dbb5f URL: https://github.com/llvm/llvm-project/commit/0009cdbd8a3ab27b1edefa0e9a6fdf41d66dbb5f DIFF: https://github.com/llvm/llvm-project/commit/0009cdbd8a3ab27b1edefa0e9a6fdf41d66dbb5f.diff LOG: [clang][NFC] Remove IgnoreLinkageSpecDecls The Itanium mangler uses IgnoreLinkageSpecDecls to strip linkage spec contexts. It doesn't do this consistently, but there is no need for it to do it at all. getEffectiveDeclContext never returns a linkage spec, as it either recurses, uses getRedeclContext (which itself removes the specs), or gets the decl context of non-namespace entities. This patch removes the function and all calls to it. For safety I add a couple of asserts to make sure we never get them. Reviewed By: ChuanqiXu Differential Revision: https://reviews.llvm.org/D119748 Added: Modified: clang/lib/AST/ItaniumMangle.cpp Removed: diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index b15669d426bd6..b92a6a07ff1f7 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -862,18 +862,9 @@ void CXXNameMangler::mangleFunctionEncodingBareType(const FunctionDecl *FD) { MangleReturnType, FD); } -static const DeclContext *IgnoreLinkageSpecDecls(const DeclContext *DC) { - while (isa(DC)) { -DC = getEffectiveParentContext(DC); - } - - return DC; -} - /// Return whether a given namespace is the 'std' namespace. static bool isStd(const NamespaceDecl *NS) { - if (!IgnoreLinkageSpecDecls(getEffectiveParentContext(NS)) -->isTranslationUnit()) + if (!getEffectiveParentContext(NS)->isTranslationUnit()) return false; const IdentifierInfo *II = NS->getOriginalNamespace()->getIdentifier(); @@ -978,7 +969,7 @@ void CXXNameMangler::mangleNameWithAbiTags(GlobalDecl GD, return; } - DC = IgnoreLinkageSpecDecls(DC); + assert(!isa(DC) && "context cannot be LinkageSpecDecl"); if (isLocalContainerContext(DC)) { mangleLocalName(GD, AdditionalAbiTags); @@ -1054,7 +1045,7 @@ void CXXNameMangler::mangleModuleNamePrefix(StringRef Name) { void CXXNameMangler::mangleTemplateName(const TemplateDecl *TD, const TemplateArgument *TemplateArgs, unsigned NumTemplateArgs) { - const DeclContext *DC = IgnoreLinkageSpecDecls(getEffectiveDeclContext(TD)); + const DeclContext *DC = getEffectiveDeclContext(TD); if (DC->isTranslationUnit() || isStdNamespace(DC)) { mangleUnscopedTemplateName(TD, nullptr); @@ -1070,7 +1061,7 @@ void CXXNameMangler::mangleUnscopedName(GlobalDecl GD, // ::= // ::= St# ::std:: - if (isStdNamespace(IgnoreLinkageSpecDecls(getEffectiveDeclContext(ND + if (isStdNamespace(getEffectiveDeclContext(ND))) Out << "St"; mangleUnqualifiedName(GD, AdditionalAbiTags); @@ -2030,7 +2021,7 @@ void CXXNameMangler::manglePrefix(const DeclContext *DC, bool NoFunction) { // ::= # empty // ::= - DC = IgnoreLinkageSpecDecls(DC); + assert(!isa(DC) && "prefix cannot be LinkageSpecDecl"); if (DC->isTranslationUnit()) return; ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] 725d57c - AST: Make getEffectiveDeclContext() a member function of ItaniumMangleContextImpl. NFCI.
Author: Peter Collingbourne Date: 2022-05-24T10:53:49-07:00 New Revision: 725d57c39039246b6fed1908f7e2eeb8d8afe17d URL: https://github.com/llvm/llvm-project/commit/725d57c39039246b6fed1908f7e2eeb8d8afe17d DIFF: https://github.com/llvm/llvm-project/commit/725d57c39039246b6fed1908f7e2eeb8d8afe17d.diff LOG: AST: Make getEffectiveDeclContext() a member function of ItaniumMangleContextImpl. NFCI. In an upcoming change we are going to need to access mangler state from the getEffectiveDeclContext() function. Therefore, make it a member function of ItaniumMangleContextImpl. Any callers that are not currently members of ItaniumMangleContextImpl or CXXNameMangler are made members of one or the other depending on where they are called from. Differential Revision: https://reviews.llvm.org/D116773 Added: Modified: clang/lib/AST/ItaniumMangle.cpp Removed: diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index b92a6a07ff1f7..1cda21446c85e 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -40,65 +40,10 @@ using namespace clang; namespace { -/// Retrieve the declaration context that should be used when mangling the given -/// declaration. -static const DeclContext *getEffectiveDeclContext(const Decl *D) { - // The ABI assumes that lambda closure types that occur within - // default arguments live in the context of the function. However, due to - // the way in which Clang parses and creates function declarations, this is - // not the case: the lambda closure type ends up living in the context - // where the function itself resides, because the function declaration itself - // had not yet been created. Fix the context here. - if (const CXXRecordDecl *RD = dyn_cast(D)) { -if (RD->isLambda()) - if (ParmVarDecl *ContextParam -= dyn_cast_or_null(RD->getLambdaContextDecl())) -return ContextParam->getDeclContext(); - } - - // Perform the same check for block literals. - if (const BlockDecl *BD = dyn_cast(D)) { -if (ParmVarDecl *ContextParam - = dyn_cast_or_null(BD->getBlockManglingContextDecl())) - return ContextParam->getDeclContext(); - } - - const DeclContext *DC = D->getDeclContext(); - if (isa(DC) || isa(DC) || - isa(DC)) { -return getEffectiveDeclContext(cast(DC)); - } - - if (const auto *VD = dyn_cast(D)) -if (VD->isExternC()) - return VD->getASTContext().getTranslationUnitDecl(); - - if (const auto *FD = dyn_cast(D)) -if (FD->isExternC()) - return FD->getASTContext().getTranslationUnitDecl(); - - return DC->getRedeclContext(); -} - -static const DeclContext *getEffectiveParentContext(const DeclContext *DC) { - return getEffectiveDeclContext(cast(DC)); -} - static bool isLocalContainerContext(const DeclContext *DC) { return isa(DC) || isa(DC) || isa(DC); } -static const RecordDecl *GetLocalClassDecl(const Decl *D) { - const DeclContext *DC = getEffectiveDeclContext(D); - while (!DC->isNamespace() && !DC->isTranslationUnit()) { -if (isLocalContainerContext(DC)) - return dyn_cast(D); -D = cast(DC); -DC = getEffectiveDeclContext(D); - } - return nullptr; -} - static const FunctionDecl *getStructor(const FunctionDecl *fn) { if (const FunctionTemplateDecl *ftd = fn->getPrimaryTemplate()) return ftd->getTemplatedDecl(); @@ -249,6 +194,14 @@ class ItaniumMangleContextImpl : public ItaniumMangleContext { return DiscriminatorOverride; } + const DeclContext *getEffectiveDeclContext(const Decl *D); + const DeclContext *getEffectiveParentContext(const DeclContext *DC) { +return getEffectiveDeclContext(cast(DC)); + } + + bool isInternalLinkageDecl(const NamedDecl *ND); + const DeclContext *IgnoreLinkageSpecDecls(const DeclContext *DC); + /// @} }; @@ -427,6 +380,15 @@ class CXXNameMangler { ASTContext &getASTContext() const { return Context.getASTContext(); } + bool isStd(const NamespaceDecl *NS); + bool isStdNamespace(const DeclContext *DC); + + const RecordDecl *GetLocalClassDecl(const Decl *D); + const DeclContext *IgnoreLinkageSpecDecls(const DeclContext *DC); + bool isSpecializedAs(QualType S, llvm::StringRef Name, QualType A); + bool isStdCharSpecialization(const ClassTemplateSpecializationDecl *SD, + llvm::StringRef Name, bool HasAllocator); + public: CXXNameMangler(ItaniumMangleContextImpl &C, raw_ostream &Out_, const NamedDecl *D = nullptr, bool NullOut_ = false) @@ -628,7 +590,48 @@ class CXXNameMangler { } -static bool isInternalLinkageDecl(const NamedDecl *ND) { +/// Retrieve the declaration context that should be used when mangling the given +/// declaration. +const DeclContext * +ItaniumMangleContextImpl::getEffectiveDeclContext(const Decl *D) { + // The ABI assumes that lambda closure types that occur within + // def
[llvm-branch-commits] [clang] fecfc83 - AST: Move __va_list tag back to std conditionally on AArch64.
Author: Peter Collingbourne Date: 2022-05-24T10:53:49-07:00 New Revision: fecfc8394484be0ff686e2c936eb494ce6a19645 URL: https://github.com/llvm/llvm-project/commit/fecfc8394484be0ff686e2c936eb494ce6a19645 DIFF: https://github.com/llvm/llvm-project/commit/fecfc8394484be0ff686e2c936eb494ce6a19645.diff LOG: AST: Move __va_list tag back to std conditionally on AArch64. In post-commit feedback on D104830 Jessica Clarke pointed out that unconditionally adding __va_list to the std namespace caused namespace debug info to be emitted in C, which is not only inappropriate but turned out to confuse the dtrace tool. Therefore, move __va_list back to std only in C++ so that the correct debug info is generated. We also considered moving __va_list to the top level unconditionally but this would contradict the specification and be visible to AST matchers and such, so make it conditional on the language mode. To avoid breaking name mangling for __va_list, teach the Itanium name mangler to always mangle it as if it were in the std namespace when targeting ARM architectures. This logic is not needed for the Microsoft name mangler because Microsoft platforms define va_list as a typedef of char *. Depends on D116773 Differential Revision: https://reviews.llvm.org/D116774 Added: Modified: clang/lib/AST/ASTContext.cpp clang/lib/AST/ItaniumMangle.cpp clang/test/CodeGen/aarch64-varargs.c clang/test/CodeGen/arm64-be-hfa-vararg.c clang/test/Headers/stdarg.cpp Removed: diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 5fa2d46de89b2..c873ff0515e1c 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -8547,21 +8547,18 @@ static TypedefDecl *CreateVoidPtrBuiltinVaListDecl(const ASTContext *Context) { static TypedefDecl * CreateAArch64ABIBuiltinVaListDecl(const ASTContext *Context) { + // struct __va_list RecordDecl *VaListTagDecl = Context->buildImplicitRecord("__va_list"); - // namespace std { struct __va_list { - // Note that we create the namespace even in C. This is intentional so that - // the type is consistent between C and C++, which is important in cases where - // the types need to match between translation units (e.g. with - // -fsanitize=cfi-icall). Ideally we wouldn't have created this namespace at - // all, but it's now part of the ABI (e.g. in mangled names), so we can't - // change it. - auto *NS = NamespaceDecl::Create( - const_cast(*Context), Context->getTranslationUnitDecl(), - /*Inline*/ false, SourceLocation(), SourceLocation(), - &Context->Idents.get("std"), - /*PrevDecl*/ nullptr); - NS->setImplicit(); - VaListTagDecl->setDeclContext(NS); + if (Context->getLangOpts().CPlusPlus) { +// namespace std { struct __va_list { +auto *NS = NamespaceDecl::Create( +const_cast(*Context), Context->getTranslationUnitDecl(), +/*Inline*/ false, SourceLocation(), SourceLocation(), +&Context->Idents.get("std"), +/*PrevDecl*/ nullptr); +NS->setImplicit(); +VaListTagDecl->setDeclContext(NS); + } VaListTagDecl->startDefinition(); diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 1cda21446c85e..68d4d1271cdba 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -71,6 +71,7 @@ class ItaniumMangleContextImpl : public ItaniumMangleContext { llvm::DenseMap Discriminator; llvm::DenseMap Uniquifier; const DiscriminatorOverrideTy DiscriminatorOverride = nullptr; + NamespaceDecl *StdNamespace = nullptr; bool NeedsUniqueInternalLinkageNames = false; @@ -194,6 +195,8 @@ class ItaniumMangleContextImpl : public ItaniumMangleContext { return DiscriminatorOverride; } + NamespaceDecl *getStdNamespace(); + const DeclContext *getEffectiveDeclContext(const Decl *D); const DeclContext *getEffectiveParentContext(const DeclContext *DC) { return getEffectiveDeclContext(cast(DC)); @@ -590,6 +593,18 @@ class CXXNameMangler { } +NamespaceDecl *ItaniumMangleContextImpl::getStdNamespace() { + if (!StdNamespace) { +StdNamespace = NamespaceDecl::Create( +getASTContext(), getASTContext().getTranslationUnitDecl(), +/*Inline*/ false, SourceLocation(), SourceLocation(), +&getASTContext().Idents.get("std"), +/*PrevDecl*/ nullptr); +StdNamespace->setImplicit(); + } + return StdNamespace; +} + /// Retrieve the declaration context that should be used when mangling the given /// declaration. const DeclContext * @@ -614,6 +629,17 @@ ItaniumMangleContextImpl::getEffectiveDeclContext(const Decl *D) { return ContextParam->getDeclContext(); } + // On ARM and AArch64, the va_list tag is always mangled as if in the std + // namespace. We do not represent va_list as actually being in the std + // namespace in C because this would r
[llvm-branch-commits] [clang] e6de9ed - [CUDA][HIP] Externalize kernels in anonymous name space
Author: Yaxun (Sam) Liu Date: 2022-05-24T15:02:58-07:00 New Revision: e6de9ed37308e46560243229dd78e84542f37ead URL: https://github.com/llvm/llvm-project/commit/e6de9ed37308e46560243229dd78e84542f37ead DIFF: https://github.com/llvm/llvm-project/commit/e6de9ed37308e46560243229dd78e84542f37ead.diff LOG: [CUDA][HIP] Externalize kernels in anonymous name space kernels in anonymous name space needs to have unique name to avoid duplicate symbols. Fixes: https://github.com/llvm/llvm-project/issues/54560 Reviewed by: Artem Belevich Differential Revision: https://reviews.llvm.org/D123353 (cherry picked from commit 4ea1d435099f992cc16127619b0feb64e070630d) Added: clang/test/CodeGenCUDA/kernel-in-anon-ns.cu Modified: clang/include/clang/AST/ASTContext.h clang/lib/AST/ASTContext.cpp clang/lib/CodeGen/CGCUDANV.cpp clang/lib/CodeGen/CodeGenModule.cpp clang/lib/CodeGen/CodeGenModule.h Removed: diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 63c11e237d6c8..1bd5d7a6c1d71 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -3279,10 +3279,10 @@ OPT_LIST(V) /// Return a new OMPTraitInfo object owned by this context. OMPTraitInfo &getNewOMPTraitInfo(); - /// Whether a C++ static variable may be externalized. + /// Whether a C++ static variable or CUDA/HIP kernel may be externalized. bool mayExternalizeStaticVar(const Decl *D) const; - /// Whether a C++ static variable should be externalized. + /// Whether a C++ static variable or CUDA/HIP kernel should be externalized. bool shouldExternalizeStaticVar(const Decl *D) const; StringRef getCUIDHash() const; diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index c873ff0515e1c..b554cf833b443 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -12263,14 +12263,16 @@ bool ASTContext::mayExternalizeStaticVar(const Decl *D) const { (D->hasAttr() && !D->getAttr()->isImplicit()); // CUDA/HIP: static managed variables need to be externalized since it is - // a declaration in IR, therefore cannot have internal linkage. - return IsStaticVar && - (D->hasAttr() || IsExplicitDeviceVar); + // a declaration in IR, therefore cannot have internal linkage. Kernels in + // anonymous name space needs to be externalized to avoid duplicate symbols. + return (IsStaticVar && + (D->hasAttr() || IsExplicitDeviceVar)) || + (D->hasAttr() && D->isInAnonymousNamespace()); } bool ASTContext::shouldExternalizeStaticVar(const Decl *D) const { return mayExternalizeStaticVar(D) && - (D->hasAttr() || + (D->hasAttr() || D->hasAttr() || CUDADeviceVarODRUsedByHost.count(cast(D))); } diff --git a/clang/lib/CodeGen/CGCUDANV.cpp b/clang/lib/CodeGen/CGCUDANV.cpp index c4e3f7f54f4f2..414e61f25fb3a 100644 --- a/clang/lib/CodeGen/CGCUDANV.cpp +++ b/clang/lib/CodeGen/CGCUDANV.cpp @@ -287,7 +287,7 @@ std::string CGNVCUDARuntime::getDeviceSideName(const NamedDecl *ND) { SmallString<256> Buffer; llvm::raw_svector_ostream Out(Buffer); Out << DeviceSideName; -CGM.printPostfixForExternalizedStaticVar(Out); +CGM.printPostfixForExternalizedDecl(Out, ND); DeviceSideName = std::string(Out.str()); } return DeviceSideName; diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 29806b65e984e..65b9f4e40dc1c 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1367,7 +1367,7 @@ static std::string getMangledNameImpl(CodeGenModule &CGM, GlobalDecl GD, if (CGM.getContext().shouldExternalizeStaticVar(ND) && CGM.getLangOpts().GPURelocatableDeviceCode && CGM.getLangOpts().CUDAIsDevice && !CGM.getLangOpts().CUID.empty()) -CGM.printPostfixForExternalizedStaticVar(Out); +CGM.printPostfixForExternalizedDecl(Out, ND); return std::string(Out.str()); } @@ -1455,7 +1455,7 @@ StringRef CodeGenModule::getMangledName(GlobalDecl GD) { // directly between host- and device-compilations, the host- and // device-mangling in host compilation could help catching certain ones. assert(!isa(ND) || !ND->hasAttr() || - getLangOpts().CUDAIsDevice || + getContext().shouldExternalizeStaticVar(ND) || getLangOpts().CUDAIsDevice || (getContext().getAuxTargetInfo() && (getContext().getAuxTargetInfo()->getCXXABI() != getContext().getTargetInfo().getCXXABI())) || @@ -6645,7 +6645,8 @@ bool CodeGenModule::stopAutoInit() { return false; } -void CodeGenModule::printPostfixForExternalizedStaticVar( -llvm::raw_ostream &OS) const { - OS << "__static__" << getContext().getCUIDHash(); +void CodeGenModule::printPostfixForExternalizedDecl(llvm::raw_o
[llvm-branch-commits] [clang] 29f1039 - [CUDA][HIP] Externalize kernels with internal linkage
Author: Yaxun (Sam) Liu Date: 2022-05-24T15:02:58-07:00 New Revision: 29f1039a7285a5c3a9c353d054140bf2556d4c4d URL: https://github.com/llvm/llvm-project/commit/29f1039a7285a5c3a9c353d054140bf2556d4c4d DIFF: https://github.com/llvm/llvm-project/commit/29f1039a7285a5c3a9c353d054140bf2556d4c4d.diff LOG: [CUDA][HIP] Externalize kernels with internal linkage This patch is a continuation of https://reviews.llvm.org/D123353. Not only kernels in anonymous namespace, but also template kernels with template arguments in anonymous namespace need to be externalized. To be more generic, this patch checks the linkage of a kernel assuming the kernel does not have __global__ attribute. If the linkage is internal then clang will externalize it. This patch also fixes the postfix for externalized symbol since nvptx does not allow '.' in symbol name. Reviewed by: Artem Belevich Differential Revision: https://reviews.llvm.org/D124189 Fixes: https://github.com/llvm/llvm-project/issues/54560 (cherry picked from commit 04fb81674ed7981397ffe70fe6a07b7168f6fe2f) Added: Modified: clang/lib/AST/ASTContext.cpp clang/lib/CodeGen/CodeGenModule.cpp clang/test/CodeGenCUDA/device-var-linkage.cu clang/test/CodeGenCUDA/kernel-in-anon-ns.cu clang/test/CodeGenCUDA/managed-var.cu clang/test/CodeGenCUDA/static-device-var-rdc.cu Removed: diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index b554cf833b443..e4b3827b87140 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -12267,7 +12267,9 @@ bool ASTContext::mayExternalizeStaticVar(const Decl *D) const { // anonymous name space needs to be externalized to avoid duplicate symbols. return (IsStaticVar && (D->hasAttr() || IsExplicitDeviceVar)) || - (D->hasAttr() && D->isInAnonymousNamespace()); + (D->hasAttr() && + basicGVALinkageForFunction(*this, cast(D)) == + GVA_Internal); } bool ASTContext::shouldExternalizeStaticVar(const Decl *D) const { diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 65b9f4e40dc1c..2777fc22600db 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -6647,6 +6647,12 @@ bool CodeGenModule::stopAutoInit() { void CodeGenModule::printPostfixForExternalizedDecl(llvm::raw_ostream &OS, const Decl *D) const { - OS << (isa(D) ? "__static__" : ".anon.") - << getContext().getCUIDHash(); + StringRef Tag; + // ptxas does not allow '.' in symbol names. On the other hand, HIP prefers + // postfix beginning with '.' since the symbol name can be demangled. + if (LangOpts.HIP) +Tag = (isa(D) ? ".static." : ".intern."); + else +Tag = (isa(D) ? "__static__" : "__intern__"); + OS << Tag << getContext().getCUIDHash(); } diff --git a/clang/test/CodeGenCUDA/device-var-linkage.cu b/clang/test/CodeGenCUDA/device-var-linkage.cu index d830802c82061..2c3f6023acae8 100644 --- a/clang/test/CodeGenCUDA/device-var-linkage.cu +++ b/clang/test/CodeGenCUDA/device-var-linkage.cu @@ -1,15 +1,18 @@ -// RUN: %clang_cc1 -triple nvptx -fcuda-is-device \ +// RUN: %clang_cc1 -triple amdgcn -fcuda-is-device \ // RUN: -emit-llvm -o - -x hip %s \ // RUN: | FileCheck -check-prefixes=DEV,NORDC %s -// RUN: %clang_cc1 -triple nvptx -fcuda-is-device \ +// RUN: %clang_cc1 -triple amdgcn -fcuda-is-device \ // RUN: -fgpu-rdc -cuid=abc -emit-llvm -o - -x hip %s \ // RUN: | FileCheck -check-prefixes=DEV,RDC %s -// RUN: %clang_cc1 -triple nvptx \ +// RUN: %clang_cc1 -triple x86_64-unknown-gnu-linux \ // RUN: -emit-llvm -o - -x hip %s \ // RUN: | FileCheck -check-prefixes=HOST,NORDC-H %s -// RUN: %clang_cc1 -triple nvptx \ +// RUN: %clang_cc1 -triple x86_64-unknown-gnu-linux \ // RUN: -fgpu-rdc -cuid=abc -emit-llvm -o - -x hip %s \ // RUN: | FileCheck -check-prefixes=HOST,RDC-H %s +// RUN: %clang_cc1 -triple nvptx -fcuda-is-device \ +// RUN: -fgpu-rdc -cuid=abc -emit-llvm -o - %s \ +// RUN: | FileCheck -check-prefixes=CUDA %s #include "Inputs/cuda.h" @@ -24,7 +27,9 @@ __constant__ int v2; // DEV-DAG: @v3 = addrspace(1) externally_initialized global i32 addrspace(1)* null // NORDC-H-DAG: @v3 = internal externally_initialized global i32* null // RDC-H-DAG: @v3 = externally_initialized global i32* null +#if __HIP__ __managed__ int v3; +#endif // DEV-DAG: @ev1 = external addrspace(1) global i32 // HOST-DAG: @ev1 = external global i32 @@ -34,25 +39,35 @@ extern __device__ int ev1; extern __constant__ int ev2; // DEV-DAG: @ev3 = external addrspace(1) externally_initialized global i32 addrspace(1)* // HOST-DAG: @ev3 = external externally_initialized global i32* +#if __HIP__ extern __managed__ int ev3; +#endif // NORDC-DAG: @_ZL3sv1 = addrspace(1) externally_initialized global i32 0 -/