[PATCH] D47673: [Coroutines] Less IR for noexcept await_resume
modocache created this revision. modocache added reviewers: GorNishanov, EricWF. Herald added a subscriber: cfe-commits. In his review of https://reviews.llvm.org/D45860, @GorNishanov suggested avoiding generating additional exception-handling IR in the case that the resume function was marked as 'noexcept', and exceptions could not occur. This implements that suggestion. Test Plan: `check-clang` Repository: rC Clang https://reviews.llvm.org/D47673 Files: lib/CodeGen/CGCoroutine.cpp test/CodeGenCoroutines/coro-await-resume-eh.cpp Index: test/CodeGenCoroutines/coro-await-resume-eh.cpp === --- test/CodeGenCoroutines/coro-await-resume-eh.cpp +++ test/CodeGenCoroutines/coro-await-resume-eh.cpp @@ -18,18 +18,18 @@ void await_resume() { throw 42; } }; -struct task { +struct throwing_task { struct promise_type { -task get_return_object() { return task{}; } +auto get_return_object() { return throwing_task{}; } auto initial_suspend() { return throwing_awaitable{}; } auto final_suspend() { return coro::suspend_never{}; } void return_void() {} void unhandled_exception() {} }; }; // CHECK-LABEL: define void @_Z1fv() -task f() { +throwing_task f() { // A variable RESUMETHREW is used to keep track of whether the body // of 'await_resume' threw an exception. Exceptions thrown in // 'await_resume' are unwound to RESUMELPAD. @@ -50,7 +50,7 @@ // CHECK: [[RESUMELPAD]]: // CHECK: br label %[[RESUMECATCH:.+]] // CHECK: [[RESUMECATCH]]: - // CHECK: invoke void @_ZN4task12promise_type19unhandled_exceptionEv + // CHECK: invoke void @_ZN13throwing_task12promise_type19unhandled_exceptionEv // CHECK-NEXT: to label %[[RESUMEENDCATCH:.+]] unwind label // CHECK: [[RESUMEENDCATCH]]: // CHECK-NEXT: invoke void @__cxa_end_catch() @@ -67,15 +67,42 @@ // CHECK-NEXT: br i1 %[[RESUMETHREWLOAD]], label %[[RESUMEDCONT:.+]], label %[[RESUMEDBODY:.+]] // CHECK: [[RESUMEDBODY]]: - // CHECK: invoke void @_ZN4task12promise_type11return_voidEv + // CHECK: invoke void @_ZN13throwing_task12promise_type11return_voidEv // CHECK-NEXT: to label %[[REDUMEDBODYCONT:.+]] unwind label // CHECK: [[REDUMEDBODYCONT]]: // CHECK-NEXT: br label %[[COROFINAL:.+]] // CHECK: [[RESUMEDCONT]]: // CHECK-NEXT: br label %[[COROFINAL]] // CHECK: [[COROFINAL]]: - // CHECK-NEXT: invoke void @_ZN4task12promise_type13final_suspendEv + // CHECK-NEXT: invoke void @_ZN13throwing_task12promise_type13final_suspendEv + co_return; +} + +struct noexcept_awaitable { + bool await_ready() { return true; } + void await_suspend(coro::coroutine_handle<>) {} + void await_resume() noexcept {} +}; + +struct noexcept_task { + struct promise_type { +auto get_return_object() { return noexcept_task{}; } +auto initial_suspend() { return noexcept_awaitable{}; } +auto final_suspend() { return coro::suspend_never{}; } +void return_void() {} +void unhandled_exception() {} + }; +}; + +// CHECK-LABEL: define void @_Z1gv() +noexcept_task g() { + // If the await_resume function is marked as noexcept, none of the additional + // conditions that are present in f() above are added to the IR. + // This means that no i1 are stored before or after calling await_resume: + // CHECK: init.ready: + // CHECK-NEXT: call void @_ZN18noexcept_awaitable12await_resumeEv + // CHECK-NOT: store i1 false, i1* co_return; } Index: lib/CodeGen/CGCoroutine.cpp === --- lib/CodeGen/CGCoroutine.cpp +++ lib/CodeGen/CGCoroutine.cpp @@ -217,8 +217,19 @@ // Emit await_resume expression. CGF.EmitBlock(ReadyBlock); + + // Exception handling requires additional IR. If the 'await_resume' function + // is marked as 'noexcept', we avoid generating this additional IR. + bool ResumeCanThrow = true; + if (const auto *MCE = dyn_cast(S.getResumeExpr())) +if (const auto *Proto = +MCE->getMethodDecl()->getType()->getAs()) + if (isNoexceptExceptionSpec(Proto->getExceptionSpecType()) && + Proto->canThrow() == CT_Cannot) +ResumeCanThrow = false; + CXXTryStmt *TryStmt = nullptr; - if (Coro.ExceptionHandler && Kind == AwaitKind::Init) { + if (Coro.ExceptionHandler && Kind == AwaitKind::Init && ResumeCanThrow) { Coro.ResumeEHVar = CGF.CreateTempAlloca(Builder.getInt1Ty(), Prefix + Twine("resume.eh")); Builder.CreateFlagStore(true, Coro.ResumeEHVar); @@ -625,12 +636,20 @@ CurCoro.Data->CurrentAwaitKind = AwaitKind::Normal; if (CurCoro.Data->ExceptionHandler) { - BasicBlock *BodyBB = createBasicBlock("coro.resumed.body"); - BasicBlock *ContBB = createBasicBlock("coro.resumed.cont"); - Value *SkipBody = - Builder.CreateFlagLoad(CurCoro.Data->ResumeEHVar, "coro.resumed.eh"); - Builder.CreateCondBr(SkipBody, ContBB, BodyBB); - EmitBlock(BodyBB); + // If we gene
[PATCH] D46805: If some platforms do not support an attribute, we should exclude the platform
HLJ2009 added a comment. In https://reviews.llvm.org/D46805#1117091, @sunfish wrote: > In https://reviews.llvm.org/D46805#1115681, @rsmith wrote: > > > In https://reviews.llvm.org/D46805#1113358, @aaron.ballman wrote: > > > > > @rsmith -- do the object file formats listed look correct to you? > > > > > > They look at least plausible. We should be able to test whether LLVM can > > actually emit aliases on each of these targets easily enough... > > > > However, I get this error for any WAsm compilation I try: > > > > fatal error: error in backend: section size does not fit in a uint32_t > > > > ... so I have no idea if aliases are/will be supported there. Perhaps > > @sunfish can tell us :) > > > Yes, they are intended to be supported. It sounds like you found a bug, > though I've not been able to reproduce it in simple tests. Comment at: include/clang/Basic/Attr.td:322 +def TargetSupportsAlias : TargetSpec { + let ObjectFormats = ["COFF", "ELF", "Wasm"]; +} aaron.ballman wrote: > Did you verify that Wasm supports the alias attribute? If it is supported, it > might be nice to add a test to `CodeGen/alias.c` to demonstrate it. Similar > for COFF. Yes, I used the following command line to test my test file. clang -cc1 -triple wasm32-unknown-unknown -fsyntax-only -verify attr-alias-has.c clang -cc1 -triple wasm64-unknown-unknown -fsyntax-only -verify attr-alias-has.c The test result is ok. ok, I will update it. Comment at: test/Sema/attr-alias-has.c:5 +// RUN: %clang_cc1 -triple wasm32-unknown-unknown -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple wasm64-unknown-unknown -fsyntax-only -verify %s + aaron.ballman wrote: > I'd like to see a test that the "attribute not supported on target" > diagnostic is being generated. I'd recommend something along these lines: > ``` > void g() {} > void f() __attribute__((alias("g"))); > #if !__has_attribute(alias) > // expected-error@-2{{expected diagnostic text}} > #else > // expected-no-diagnostics > #endif > ``` ok, I will update it. Repository: rC Clang https://reviews.llvm.org/D46805 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D47201: [CUDA] Implement nv_weak attribute for functions
Hahnfeld added a comment. In https://reviews.llvm.org/D47201#1119254, @aaron.ballman wrote: > In https://reviews.llvm.org/D47201#1119249, @tra wrote: > > > IIUIC, nv_weak is a synonym for weak (why, oh why did they need > > it?) > > You may need to hunt down and change few other places that deal with the > > weak attribute. > > E.g.: > > https://github.com/llvm-project/llvm-project-20170507/blob/master/clang/lib/AST/Decl.cpp#L4267 > > > > https://github.com/llvm-project/llvm-project-20170507/blob/master/clang/lib/CodeGen/ItaniumCXXABI.cpp#L3045 > > > If it is truly a synonym for weak, then a better implementation would be to > make no semantic distinction between the two attributes -- just add new > spellings to weak. If you need to make minor distinctions between the > spellings, you can do it using accessors on the attribute. I first went with this approach but then thought it would be better to restrict the new attribute as much as possible. That's why I added a completely new one which is only applicable to functions, but not to variables and `CXXRecord`s. Let me know if you'd prefer `nv_weak` to be a full alias of `weak` and I'll revert to what @aaron.ballman suggested. Repository: rC Clang https://reviews.llvm.org/D47201 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D46602: [clang-tidy] Store checks profiling info as YAML files
lebedev.ri updated this revision to Diff 149610. lebedev.ri marked 6 inline comments as done. lebedev.ri added a comment. Rebased. Addressed review notes. Repository: rCTE Clang Tools Extra https://reviews.llvm.org/D46602 Files: clang-tidy/ClangTidy.cpp clang-tidy/ClangTidy.h clang-tidy/ClangTidyDiagnosticConsumer.cpp clang-tidy/ClangTidyDiagnosticConsumer.h clang-tidy/ClangTidyProfiling.cpp clang-tidy/ClangTidyProfiling.h clang-tidy/tool/ClangTidyMain.cpp docs/ReleaseNotes.rst docs/clang-tidy/index.rst test/clang-tidy/clang-tidy-enable-check-profile-one-tu.cpp test/clang-tidy/clang-tidy-enable-check-profile-two-tu.cpp test/clang-tidy/clang-tidy-store-check-profile-one-tu.cpp Index: test/clang-tidy/clang-tidy-store-check-profile-one-tu.cpp === --- /dev/null +++ test/clang-tidy/clang-tidy-store-check-profile-one-tu.cpp @@ -0,0 +1,37 @@ +// RUN: rm -rf %T/out +// RUN: clang-tidy -enable-check-profile -checks='-*,readability-function-size' -store-check-profile=%T/out %s 2>&1 | FileCheck --match-full-lines -implicit-check-not='{{warning:|error:}}' -check-prefix=CHECK-CONSOLE %s +// RUN: cat %T/out/*-clang-tidy-store-check-profile-one-tu.cpp.yaml | FileCheck --match-full-lines -implicit-check-not='{{warning:|error:}}' -check-prefix=CHECK-FILE %s +// RUN: rm -rf %T/out +// RUN: clang-tidy -enable-check-profile -checks='-*,readability-function-size' -store-check-profile=%T/out %s 2>&1 | FileCheck --match-full-lines -implicit-check-not='{{warning:|error:}}' -check-prefix=CHECK-CONSOLE %s +// RUN: cat %T/out/*-clang-tidy-store-check-profile-one-tu.cpp.yaml | FileCheck --match-full-lines -implicit-check-not='{{warning:|error:}}' -check-prefix=CHECK-FILE %s + +// CHECK-CONSOLE-NOT: ===-=== +// CHECK-CONSOLE-NOT: {{.*}} --- Name --- +// CHECK-CONSOLE-NOT: {{.*}} readability-function-size +// CHECK-CONSOLE-NOT: {{.*}} Total +// CHECK-CONSOLE-NOT: ===-=== + +// CHECK-FILE: { +// CHECK-FILE-NEXT:"file": "{{.*}}clang-tidy-store-check-profile-one-tu.cpp", +// CHECK-FILE-NEXT:"timestamp": "{{[0-9]+}}-{{[0-9]+}}-{{[0-9]+}} {{[0-9]+}}:{{[0-9]+}}:{{[0-9]+}}.{{[0-9]+}}", +// CHECK-FILE-NEXT:"profile": { +// CHECK-FILE-NEXT: "time.clang-tidy.readability-function-size.wall": {{.*}}{{[0-9]}}.{{[0-9]+}}e{{[-+]}}{{[0-9]}}{{[0-9]}}, +// CHECK-FILE-NEXT: "time.clang-tidy.readability-function-size.user": {{.*}}{{[0-9]}}.{{[0-9]+}}e{{[-+]}}{{[0-9]}}{{[0-9]}}, +// CHECK-FILE-NEXT: "time.clang-tidy.readability-function-size.sys": {{.*}}{{[0-9]}}.{{[0-9]+}}e{{[-+]}}{{[0-9]}}{{[0-9]}} +// CHECK-FILE-NEXT: } +// CHECK-FILE-NEXT: } + +// CHECK-FILE-NOT: { +// CHECK-FILE-NOT: "file": {{.*}}clang-tidy-store-check-profile-one-tu.cpp{{.*}}, +// CHECK-FILE-NOT: "timestamp": "{{[0-9]+}}-{{[0-9]+}}-{{[0-9]+}} {{[0-9]+}}:{{[0-9]+}}:{{[0-9]+}}.{{[0-9]+}}", +// CHECK-FILE-NOT: "profile": { +// CHECK-FILE-NOT: "time.clang-tidy.readability-function-size.wall": {{.*}}{{[0-9]}}.{{[0-9]+}}e{{[-+]}}{{[0-9]}}{{[0-9]}}, +// CHECK-FILE-NOT: "time.clang-tidy.readability-function-size.user": {{.*}}{{[0-9]}}.{{[0-9]+}}e{{[-+]}}{{[0-9]}}{{[0-9]}}, +// CHECK-FILE-NOT: "time.clang-tidy.readability-function-size.sys": {{.*}}{{[0-9]}}.{{[0-9]+}}e{{[-+]}}{{[0-9]}}{{[0-9]}} +// CHECK-FILE-NOT: } +// CHECK-FILE-NOT: } + +class A { + A() {} + ~A() {} +}; Index: test/clang-tidy/clang-tidy-enable-check-profile-two-tu.cpp === --- test/clang-tidy/clang-tidy-enable-check-profile-two-tu.cpp +++ test/clang-tidy/clang-tidy-enable-check-profile-two-tu.cpp @@ -1,22 +1,31 @@ // RUN: clang-tidy -enable-check-profile -checks='-*,readability-function-size' %s %s 2>&1 | FileCheck --match-full-lines -implicit-check-not='{{warning:|error:}}' %s // CHECK: ===-=== -// CHECK-NEXT: {{.*}} --- Name --- +// CHECK-NEXT: clang-tidy checks profiling +// CHECK-NEXT: ===-=== +// CHECK-NEXT: Total Execution Time: {{.*}} seconds ({{.*}} wall clock) + +// CHECK: {{.*}} --- Name --- // CHECK-NEXT: {{.*}} readability-function-size // CHECK-NEXT: {{.*}} Total -// CHECK-NEXT: ===-=== // CHECK: ===-=== -// CHECK-NEXT: {{.*}} --- Name --- +// CHECK-NEXT: clang-tidy checks profiling +// CHECK-NEXT: ===-=== +// CHECK-NEXT: Total Execution Time: {{.*}} seconds ({{.*}} wall clock) + +// CHECK: {{.*}} --- Name --- // CHECK-NEXT: {{.*}} readability-function-size // CHECK-NEXT: {{.*}} Total -
[PATCH] D46602: [clang-tidy] Store checks profiling info as YAML files
lebedev.ri added inline comments. Comment at: clang-tidy/tool/ClangTidyMain.cpp:342-347 +if (!llvm::sys::fs::exists(AbsolutePath)) { + // If the destination prefix does not exist, don't try to use real_path(). + return AbsolutePath; +} +SmallString<256> dest; +if (std::error_code EC = llvm::sys::fs::real_path(AbsolutePath, dest)) { aaron.ballman wrote: > This creates a TOCTOU bug; can you call `real_path()` without checking for > existence and instead check the error code to decide whether to spit out an > error or return `AbsolutePath`? Hmm, i think this can just go away. Repository: rCTE Clang Tools Extra https://reviews.llvm.org/D46602 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D47358: : Implement {un, }synchronized_pool_resource.
Quuxplusone updated this revision to Diff 149611. Quuxplusone added a comment. - Split up the unit tests. - Refactor to shrink the memory layout of the resource object itself. Before this patch `sizeof(unsynchronized_pool_resource)==48`. After this patch `sizeof(unsynchronized_pool_resource) == 32`. Repository: rCXX libc++ https://reviews.llvm.org/D47358 Files: include/experimental/memory_resource src/experimental/memory_resource.cpp test/std/experimental/memory/memory.resource.pool/memory.resource.pool.ctor/ctor_does_not_allocate.pass.cpp test/std/experimental/memory/memory.resource.pool/memory.resource.pool.ctor/sync_with_default_resource.pass.cpp test/std/experimental/memory/memory.resource.pool/memory.resource.pool.ctor/unsync_with_default_resource.pass.cpp test/std/experimental/memory/memory.resource.pool/memory.resource.pool.mem/equality.pass.cpp test/std/experimental/memory/memory.resource.pool/memory.resource.pool.mem/sync_allocate.pass.cpp test/std/experimental/memory/memory.resource.pool/memory.resource.pool.mem/sync_allocate_overaligned_request.pass.cpp test/std/experimental/memory/memory.resource.pool/memory.resource.pool.mem/sync_allocate_reuse_blocks.pass.cpp test/std/experimental/memory/memory.resource.pool/memory.resource.pool.mem/unsync_allocate.pass.cpp test/std/experimental/memory/memory.resource.pool/memory.resource.pool.mem/unsync_allocate_overaligned_request.pass.cpp test/std/experimental/memory/memory.resource.pool/memory.resource.pool.mem/unsync_allocate_reuse_blocks.pass.cpp test/std/experimental/memory/memory.resource.pool/pool_options.pass.cpp test/support/count_new.hpp Index: test/support/count_new.hpp === --- test/support/count_new.hpp +++ test/support/count_new.hpp @@ -211,6 +211,11 @@ return disable_checking || n != delete_called; } +bool checkDeleteCalledGreaterThan(int n) const +{ +return disable_checking || delete_called > n; +} + bool checkAlignedNewCalledEq(int n) const { return disable_checking || n == aligned_new_called; Index: test/std/experimental/memory/memory.resource.pool/pool_options.pass.cpp === --- /dev/null +++ test/std/experimental/memory/memory.resource.pool/pool_options.pass.cpp @@ -0,0 +1,25 @@ +//===--===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===--===// + +// UNSUPPORTED: c++98, c++03, c++11, c++14 +// UNSUPPORTED: apple-clang-7 + +// + +// struct pool_options + +#include +#include + +int main() +{ +const std::experimental::pmr::pool_options p; +assert(p.max_blocks_per_chunk == 0); +assert(p.largest_required_pool_block == 0); +} Index: test/std/experimental/memory/memory.resource.pool/memory.resource.pool.mem/unsync_allocate_reuse_blocks.pass.cpp === --- /dev/null +++ test/std/experimental/memory/memory.resource.pool/memory.resource.pool.mem/unsync_allocate_reuse_blocks.pass.cpp @@ -0,0 +1,53 @@ +//===--===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===--===// + +// UNSUPPORTED: c++98, c++03 + +// + +// class unsynchronized_pool_resource + +#include +#include + +#include "count_new.hpp" + +static bool is_aligned_to(void *p, size_t alignment) +{ +void *p2 = p; +size_t space = 1; +void *result = std::align(alignment, 1, p2, space); +return (result == p); +} + +int main() +{ +globalMemCounter.reset(); +std::experimental::pmr::pool_options opts { 1, 256 }; +std::experimental::pmr::unsynchronized_pool_resource unsync1(opts, std::experimental::pmr::new_delete_resource()); +std::experimental::pmr::memory_resource & r1 = unsync1; + +void *ret = r1.allocate(8); +assert(ret != nullptr); +assert(is_aligned_to(ret, 8)); +assert(globalMemCounter.checkNewCalledGreaterThan(0)); +int new_called = globalMemCounter.new_called; + +// After deallocation, the pool for 8-byte blocks should have at least one vacancy. +r1.deallocate(ret, 8); +assert(globalMemCounter.new_called == new_called); +assert(globalMemCounter.checkDeleteCalledEq(0)); + +// This should return an existing block from the pool: no new allocations. +ret = r1.allocate(8); +assert(ret != nullptr); +assert(is_aligned_to(ret, 8)); +
[PATCH] D45050: [clang-tidy] New checker for not null-terminated result caused by strlen or wcslen
Charusso added a comment. In https://reviews.llvm.org/D45050#1116446, @lebedev.ri wrote: > I would like to see more negative tests. > What does it do if the len/size is a constant? > Variable that wasn't just assigned with `strlen()` return? Thanks for the comment! What do you mean by negative test? https://reviews.llvm.org/D45050 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D45050: [clang-tidy] New checker for not null-terminated result caused by strlen or wcslen
lebedev.ri added a comment. In https://reviews.llvm.org/D45050#1119973, @Charusso wrote: > In https://reviews.llvm.org/D45050#1116446, @lebedev.ri wrote: > > > I would like to see more negative tests. > > What does it do if the len/size is a constant? > > Variable that wasn't just assigned with `strlen()` return? > > > Thanks for the comment! What do you mean by negative test? The tests where the check matches and issues a warning is a positive test. The tests where the check does not match and/or does not issue a warning is a negative test. https://reviews.llvm.org/D45050 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D45050: [clang-tidy] New checker for not null-terminated result caused by strlen or wcslen
xbolva00 added a comment. In https://reviews.llvm.org/D45050#1119973, @Charusso wrote: > In https://reviews.llvm.org/D45050#1116446, @lebedev.ri wrote: > > > I would like to see more negative tests. > > What does it do if the len/size is a constant? > > Variable that wasn't just assigned with `strlen()` return? > > > Thanks for the comment! What do you mean by negative test? To prove we have no false warnings. https://reviews.llvm.org/D45050 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D47121: [NEON] Support VLD1xN intrinsics in AArch32 mode (Clang part)
This revision was automatically updated to reflect the committed changes. Closed by commit rL333819: [NEON] Support VLD1xN intrinsics in AArch32 mode (Clang part) (authored by kosarev, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D47121?vs=147718&id=149612#toc Repository: rL LLVM https://reviews.llvm.org/D47121 Files: llvm/trunk/include/llvm/IR/IntrinsicsARM.td llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp llvm/trunk/lib/Target/ARM/ARMExpandPseudoInsts.cpp llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp llvm/trunk/lib/Target/ARM/ARMInstrNEON.td llvm/trunk/test/CodeGen/ARM/arm-vld1.ll Index: llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp === --- llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp +++ llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp @@ -1761,9 +1761,7 @@ case MVT::v4f32: case MVT::v4i32: OpcodeIndex = 2; break; case MVT::v2f64: - case MVT::v2i64: OpcodeIndex = 3; -assert(NumVecs == 1 && "v2i64 type only supported for VLD1"); -break; + case MVT::v2i64: OpcodeIndex = 3; break; } EVT ResTy; @@ -3441,6 +3439,51 @@ return; } +case Intrinsic::arm_neon_vld1x2: { + static const uint16_t DOpcodes[] = { ARM::VLD1q8, ARM::VLD1q16, + ARM::VLD1q32, ARM::VLD1q64 }; + static const uint16_t QOpcodes[] = { ARM::VLD1d8QPseudo, + ARM::VLD1d16QPseudo, + ARM::VLD1d32QPseudo, + ARM::VLD1d64QPseudo }; + SelectVLD(N, false, 2, DOpcodes, QOpcodes, nullptr); + return; +} + +case Intrinsic::arm_neon_vld1x3: { + static const uint16_t DOpcodes[] = { ARM::VLD1d8TPseudo, + ARM::VLD1d16TPseudo, + ARM::VLD1d32TPseudo, + ARM::VLD1d64TPseudo }; + static const uint16_t QOpcodes0[] = { ARM::VLD1q8LowTPseudo_UPD, +ARM::VLD1q16LowTPseudo_UPD, +ARM::VLD1q32LowTPseudo_UPD, +ARM::VLD1q64LowTPseudo_UPD }; + static const uint16_t QOpcodes1[] = { ARM::VLD1q8HighTPseudo, +ARM::VLD1q16HighTPseudo, +ARM::VLD1q32HighTPseudo, +ARM::VLD1q64HighTPseudo }; + SelectVLD(N, false, 3, DOpcodes, QOpcodes0, QOpcodes1); + return; +} + +case Intrinsic::arm_neon_vld1x4: { + static const uint16_t DOpcodes[] = { ARM::VLD1d8QPseudo, + ARM::VLD1d16QPseudo, + ARM::VLD1d32QPseudo, + ARM::VLD1d64QPseudo }; + static const uint16_t QOpcodes0[] = { ARM::VLD1q8LowQPseudo_UPD, +ARM::VLD1q16LowQPseudo_UPD, +ARM::VLD1q32LowQPseudo_UPD, +ARM::VLD1q64LowQPseudo_UPD }; + static const uint16_t QOpcodes1[] = { ARM::VLD1q8HighQPseudo, +ARM::VLD1q16HighQPseudo, +ARM::VLD1q32HighQPseudo, +ARM::VLD1q64HighQPseudo }; + SelectVLD(N, false, 4, DOpcodes, QOpcodes0, QOpcodes1); + return; +} + case Intrinsic::arm_neon_vld2: { static const uint16_t DOpcodes[] = { ARM::VLD2d8, ARM::VLD2d16, ARM::VLD2d32, ARM::VLD1q64 }; Index: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp === --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp @@ -12763,6 +12763,9 @@ case ISD::INTRINSIC_W_CHAIN: switch (cast(N->getOperand(1))->getZExtValue()) { case Intrinsic::arm_neon_vld1: +case Intrinsic::arm_neon_vld1x2: +case Intrinsic::arm_neon_vld1x3: +case Intrinsic::arm_neon_vld1x4: case Intrinsic::arm_neon_vld2: case Intrinsic::arm_neon_vld3: case Intrinsic::arm_neon_vld4: @@ -14074,6 +14077,21 @@ Info.flags = MachineMemOperand::MOLoad; return true; } + case Intrinsic::arm_neon_vld1x2: + case Intrinsic::arm_neon_vld1x3: + case Intrinsic::arm_neon_vld1x4: { +Info.opc = ISD::INTRINSIC_W_CHAIN; +// Conservatively set memVT to the entire set of vectors loaded. +auto &DL = I.getCalledFunction()->getParent()->getDataLayout(); +uint64_t NumElts = DL.getTypeSizeInBits(I.getType()) / 64; +Info.memVT = EVT::getVectorVT(I.getType()->g
[PATCH] D47103: Implement strip.invariant.group
Prazek added a comment. friendly ping Repository: rL LLVM https://reviews.llvm.org/D47103 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D47299: [CodeGenCXX] Emit strip.invariant.group with -fstrict-vtable-pointers
Prazek added a comment. @rjmccall @rsmith friendly ping Repository: rL LLVM https://reviews.llvm.org/D47299 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits