From 5bc438efcf96c9ef83312c37674b03e98259a22b Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Mon, 2 Nov 2020 17:33:07 +0000 Subject: [PATCH] [AtomicExpand] Avoid creating an unnamed libcall I recently modified this pass to better support CHERI-RISC-V and while doing so I noticed that this pass was calling M->getOrInsertFunction() with the result of TLI->getLibcallName(RTLibType). However, AMDGPU fills the libcalls array with nullptr, so this creates an anonymous function instead. This patch changes expandAtomicOpToLibcall to return false in case the libcall does not exist and changes the assert() in the callees to a report_fatal_error() instead. Reviewed By: arsenm Differential Revision: https://reviews.llvm.org/D88800 --- llvm/lib/CodeGen/AtomicExpandPass.cpp | 17 +++++++++++------ .../AtomicExpand/AMDGPU/unaligned-atomic.ll | 8 +++----- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/llvm/lib/CodeGen/AtomicExpandPass.cpp b/llvm/lib/CodeGen/AtomicExpandPass.cpp index c61531c5141a..4026022caa07 100644 --- a/llvm/lib/CodeGen/AtomicExpandPass.cpp +++ b/llvm/lib/CodeGen/AtomicExpandPass.cpp @@ -1507,8 +1507,8 @@ void AtomicExpand::expandAtomicLoadToLibcall(LoadInst *I) { bool expanded = expandAtomicOpToLibcall( I, Size, I->getAlign(), I->getPointerOperand(), nullptr, nullptr, I->getOrdering(), AtomicOrdering::NotAtomic, Libcalls); - (void)expanded; - assert(expanded && "expandAtomicOpToLibcall shouldn't fail tor Load"); + if (!expanded) + report_fatal_error("expandAtomicOpToLibcall shouldn't fail for Load"); } void AtomicExpand::expandAtomicStoreToLibcall(StoreInst *I) { @@ -1520,8 +1520,8 @@ void AtomicExpand::expandAtomicStoreToLibcall(StoreInst *I) { bool expanded = expandAtomicOpToLibcall( I, Size, I->getAlign(), I->getPointerOperand(), I->getValueOperand(), nullptr, I->getOrdering(), AtomicOrdering::NotAtomic, Libcalls); - (void)expanded; - assert(expanded && "expandAtomicOpToLibcall shouldn't fail tor Store"); + if (!expanded) + report_fatal_error("expandAtomicOpToLibcall shouldn't fail for Store"); } void AtomicExpand::expandAtomicCASToLibcall(AtomicCmpXchgInst *I) { @@ -1535,8 +1535,8 @@ void AtomicExpand::expandAtomicCASToLibcall(AtomicCmpXchgInst *I) { I, Size, I->getAlign(), I->getPointerOperand(), I->getNewValOperand(), I->getCompareOperand(), I->getSuccessOrdering(), I->getFailureOrdering(), Libcalls); - (void)expanded; - assert(expanded && "expandAtomicOpToLibcall shouldn't fail tor CAS"); + if (!expanded) + report_fatal_error("expandAtomicOpToLibcall shouldn't fail for CAS"); } static ArrayRef GetRMWLibcall(AtomicRMWInst::BinOp Op) { @@ -1685,6 +1685,11 @@ bool AtomicExpand::expandAtomicOpToLibcall( return false; } + if (!TLI->getLibcallName(RTLibType)) { + // This target does not implement the requested atomic libcall so give up. + return false; + } + // Build up the function call. There's two kinds. First, the sized // variants. These calls are going to be one of the following (with // N=1,2,4,8,16): diff --git a/llvm/test/Transforms/AtomicExpand/AMDGPU/unaligned-atomic.ll b/llvm/test/Transforms/AtomicExpand/AMDGPU/unaligned-atomic.ll index 3d21e1510015..56db423af6f5 100644 --- a/llvm/test/Transforms/AtomicExpand/AMDGPU/unaligned-atomic.ll +++ b/llvm/test/Transforms/AtomicExpand/AMDGPU/unaligned-atomic.ll @@ -1,8 +1,6 @@ -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt -S -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 -atomic-expand %s | FileCheck -check-prefix=GCN %s - -; FIXME: This should not introduce a libcall, much less one to an -; anonymous function. +; RUN: not --crash opt -S -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 -atomic-expand %s 2>&1 | FileCheck %s +; The AtomicExpand pass cannot handle missing libcalls (yet) so reports a fatal error. +; CHECK: LLVM ERROR: expandAtomicOpToLibcall shouldn't fail for Load define i32 @atomic_load_global_align1(i32 addrspace(1)* %ptr) { ; GCN-LABEL: @atomic_load_global_align1(