From ef48436e62732e61cea5dde9b35b63b3ce8126f7 Mon Sep 17 00:00:00 2001 From: Johannes Doerfert Date: Tue, 8 Sep 2020 10:13:11 -0500 Subject: [PATCH] [AttributeFuncs] Consider `noundef` in `typeIncompatible` Drop `noundef` for return values that are replaced by void and make it illegal to put `noundef` on a void value. Reviewed By: fhahn Differential Revision: https://reviews.llvm.org/D87306 --- llvm/lib/IR/Attributes.cpp | 4 ++++ llvm/test/Transforms/DeadArgElim/returned.ll | 2 +- llvm/test/Verifier/align.ll | 2 +- llvm/test/Verifier/noundef.ll | 7 +++++++ 4 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 llvm/test/Verifier/noundef.ll diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp index ecb0bd69..b21d452 100644 --- a/llvm/lib/IR/Attributes.cpp +++ b/llvm/lib/IR/Attributes.cpp @@ -1859,6 +1859,10 @@ AttrBuilder AttributeFuncs::typeIncompatible(Type *Ty) { .addByValAttr(Ty) .addByRefAttr(Ty); + // Some attributes can apply to all "values" but there are no `void` values. + if (Ty->isVoidTy()) + Incompatible.addAttribute(Attribute::NoUndef); + return Incompatible; } diff --git a/llvm/test/Transforms/DeadArgElim/returned.ll b/llvm/test/Transforms/DeadArgElim/returned.ll index 0b00a11..e96faea 100644 --- a/llvm/test/Transforms/DeadArgElim/returned.ll +++ b/llvm/test/Transforms/DeadArgElim/returned.ll @@ -45,7 +45,7 @@ define internal %Ty* @test5(%Ty* %this) { ; Drop all these attributes ; CHECK-LABEL: define internal void @test6 -define internal align 8 dereferenceable_or_null(2) noalias i8* @test6() { +define internal align 8 dereferenceable_or_null(2) noundef noalias i8* @test6() { ret i8* null } diff --git a/llvm/test/Verifier/align.ll b/llvm/test/Verifier/align.ll index 762249a..38ce377 100644 --- a/llvm/test/Verifier/align.ll +++ b/llvm/test/Verifier/align.ll @@ -6,7 +6,7 @@ define void @align_non_pointer1(i32 align 4 %a) { ret void } -; CHECK: Wrong types for attribute: inalloca nest noalias nocapture nonnull readnone readonly signext zeroext byref(void) byval(void) preallocated(void) sret(void) align 1 dereferenceable(1) dereferenceable_or_null(1) +; CHECK: Wrong types for attribute: inalloca nest noalias nocapture noundef nonnull readnone readonly signext zeroext byref(void) byval(void) preallocated(void) sret(void) align 1 dereferenceable(1) dereferenceable_or_null(1) ; CHECK-NEXT: @align_non_pointer2 define align 4 void @align_non_pointer2(i32 %a) { ret void diff --git a/llvm/test/Verifier/noundef.ll b/llvm/test/Verifier/noundef.ll new file mode 100644 index 0000000..7b199cd --- /dev/null +++ b/llvm/test/Verifier/noundef.ll @@ -0,0 +1,7 @@ +; RUN: not llvm-as < %s -o /dev/null 2>&1 | FileCheck %s + +; CHECK: Wrong types for attribute: inalloca nest noalias nocapture noundef nonnull readnone readonly signext zeroext byref(void) byval(void) preallocated(void) sret(void) align 1 dereferenceable(1) dereferenceable_or_null(1) +; CHECK-NEXT: @noundef_void +define noundef void @noundef_void() { + ret void +} -- 2.7.4