From db561064f60dff6c65e9b31c709cfbd72dd24b73 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 28 Mar 2022 14:26:24 +0200 Subject: [PATCH] [GlobalOpt] Handle non-instruction MTI source (PR54572) This was reusing a cast to GlobalVariable to check for an Instruction, which means we'll try to dereference a null pointer if it's not actually a GlobalVariable. We should be casting MTI->getSource() instead. I don't think this problem is really specific to opaque pointers, but it certainly makes it a lot easier to reproduce. Fixes https://github.com/llvm/llvm-project/issues/54572. --- llvm/lib/Transforms/IPO/GlobalOpt.cpp | 2 +- llvm/test/Transforms/GlobalOpt/pr54572.ll | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 llvm/test/Transforms/GlobalOpt/pr54572.ll diff --git a/llvm/lib/Transforms/IPO/GlobalOpt.cpp b/llvm/lib/Transforms/IPO/GlobalOpt.cpp index 07c38e8..6ed6c61 100644 --- a/llvm/lib/Transforms/IPO/GlobalOpt.cpp +++ b/llvm/lib/Transforms/IPO/GlobalOpt.cpp @@ -230,7 +230,7 @@ CleanupPointerRootUsers(GlobalVariable *GV, if (MemSrc && MemSrc->isConstant()) { Changed = true; MTI->eraseFromParent(); - } else if (Instruction *I = dyn_cast(MemSrc)) { + } else if (Instruction *I = dyn_cast(MTI->getSource())) { if (I->hasOneUse()) Dead.push_back(std::make_pair(I, MTI)); } diff --git a/llvm/test/Transforms/GlobalOpt/pr54572.ll b/llvm/test/Transforms/GlobalOpt/pr54572.ll new file mode 100644 index 0000000..7a9b99e --- /dev/null +++ b/llvm/test/Transforms/GlobalOpt/pr54572.ll @@ -0,0 +1,23 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals +; RUN: opt -S -globalopt < %s | FileCheck %s + +@b = internal global ptr null +@c = internal global [2 x ptr] zeroinitializer + +declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) + +;. +; CHECK: @[[B:[a-zA-Z0-9_$"\\.-]+]] = internal unnamed_addr global ptr null +; CHECK: @[[C:[a-zA-Z0-9_$"\\.-]+]] = internal unnamed_addr constant [2 x ptr] zeroinitializer +;. +define void @test() { +; CHECK-LABEL: @test( +; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr @b, ptr getelementptr inbounds ([2 x ptr], ptr @c, i64 0, i64 1), i64 8, i1 false) +; CHECK-NEXT: ret void +; + call void @llvm.memcpy.p0.p0.i64(ptr @b, ptr getelementptr inbounds ([2 x ptr], ptr @c, i64 0, i64 1), i64 8, i1 false) + ret void +} +;. +; CHECK: attributes #[[ATTR0:[0-9]+]] = { argmemonly nofree nounwind willreturn } +;. -- 2.7.4