diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp --- a/llvm/lib/IR/Attributes.cpp +++ b/llvm/lib/IR/Attributes.cpp @@ -1859,6 +1859,10 @@ .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 --- a/llvm/test/Transforms/DeadArgElim/returned.ll +++ b/llvm/test/Transforms/DeadArgElim/returned.ll @@ -45,7 +45,7 @@ ; 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/noundef.ll b/llvm/test/Verifier/noundef.ll new file mode 100644 --- /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 sret zeroext byref(void) byval(void) preallocated(void) align 1 dereferenceable(1) dereferenceable_or_null(1) +; CHECK-NEXT: @noundef_void +define noundef void @noundef_void() { + ret void +}