Author: Alexander Shaposhnikov Date: 2022-08-16T21:28:23Z New Revision: d68ba43ad24791181280fdb0f34b6be380db7a32
URL: https://github.com/llvm/llvm-project/commit/d68ba43ad24791181280fdb0f34b6be380db7a32 DIFF: https://github.com/llvm/llvm-project/commit/d68ba43ad24791181280fdb0f34b6be380db7a32.diff LOG: [Intrinsics] Add initial support for NonNull attribute Add initial support for NonNull attribute. (https://github.com/llvm/llvm-project/issues/57113) Test plan: verify that for __thread int x; int main() { int* y = &x; return *y; } (with this patch) clang -O -fsanitize=null -S -emit-llvm -o - doesn't emit a null-pointer check Differential revision: https://reviews.llvm.org/D131872 Added: Modified: clang/test/CodeGenCXX/threadlocal_address.cpp llvm/include/llvm/IR/Intrinsics.td llvm/test/CodeGen/X86/peephole-nofold-tpoff-x86.mir llvm/test/CodeGen/X86/peephole-nofold-tpoff-x86_64.mir llvm/test/CodeGen/X86/threadlocal_address.ll llvm/utils/TableGen/CodeGenIntrinsics.h llvm/utils/TableGen/CodeGenTarget.cpp llvm/utils/TableGen/IntrinsicEmitter.cpp Removed: ################################################################################ diff --git a/clang/test/CodeGenCXX/threadlocal_address.cpp b/clang/test/CodeGenCXX/threadlocal_address.cpp index a55b1ee6e08de..625db30dd0e7b 100644 --- a/clang/test/CodeGenCXX/threadlocal_address.cpp +++ b/clang/test/CodeGenCXX/threadlocal_address.cpp @@ -20,11 +20,11 @@ int g() { // CHECK-NEXT: %[[RET:.+]] = load i32, ptr %[[IA2]], align 4 // CHECK-NEXT: ret i32 %[[RET]] // -// CHECK: declare ptr @llvm.threadlocal.address.p0(ptr) #[[ATTR_NUM:.+]] +// CHECK: declare nonnull ptr @llvm.threadlocal.address.p0(ptr nonnull) #[[ATTR_NUM:.+]] // // CHECK-O1-LABEL: @_Z1gv // CHECK-O1-NEXT: entry: -// CHECK-O1-NEXT: %[[I_ADDR:.+]] = {{.*}}call ptr @llvm.threadlocal.address.p0(ptr nonnull @i) +// CHECK-O1-NEXT: %[[I_ADDR:.+]] = {{.*}}call ptr @llvm.threadlocal.address.p0(ptr @i) // CHECK-O1-NEXT: %[[VAL:.+]] = load i32, ptr %[[I_ADDR]] // CHECK-O1-NEXT: %[[INC:.+]] = add nsw i32 %[[VAL]], 1 // CHECK-O1-NEXT: store i32 %[[INC]], ptr %[[I_ADDR]] @@ -56,7 +56,7 @@ int f() { // // CHECK-O1-LABEL: @_Z1fv // CHECK-O1-NEXT: entry: -// CHECK-O1-NEXT: %[[J_ADDR:.+]] = {{.*}}call ptr @llvm.threadlocal.address.p0(ptr nonnull @_ZZ1fvE1j) +// CHECK-O1-NEXT: %[[J_ADDR:.+]] = {{.*}}call ptr @llvm.threadlocal.address.p0(ptr @_ZZ1fvE1j) // CHECK-O1-NEXT: %[[VAL:.+]] = load i32, ptr %[[J_ADDR]] // CHECK-O1-NEXT: %[[INC:.+]] = add nsw i32 %[[VAL]], 1 // CHECK-O1-NEXT: store i32 %[[INC]], ptr %[[J_ADDR]] diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td index 2fb29a4f3eb9d..8a04c495edb11 100644 --- a/llvm/include/llvm/IR/Intrinsics.td +++ b/llvm/include/llvm/IR/Intrinsics.td @@ -84,6 +84,11 @@ class NoUndef<AttrIndex idx> : IntrinsicProperty { int ArgNo = idx.Value; } +// NonNull - The specified argument is not null. +class NonNull<AttrIndex idx> : IntrinsicProperty { + int ArgNo = idx.Value; +} + class Align<AttrIndex idx, int align> : IntrinsicProperty { int ArgNo = idx.Value; int Align = align; @@ -1407,7 +1412,8 @@ def int_ptrmask: DefaultAttrsIntrinsic<[llvm_anyptr_ty], [LLVMMatchType<0>, llvm // Intrinsic to wrap a thread local variable. def int_threadlocal_address : DefaultAttrsIntrinsic<[llvm_anyptr_ty], [LLVMMatchType<0>], - [IntrNoMem, IntrSpeculatable, IntrWillReturn]>; + [NonNull<RetIndex>, NonNull<ArgIndex<0>>, + IntrNoMem, IntrSpeculatable, IntrWillReturn]>; def int_experimental_stepvector : DefaultAttrsIntrinsic<[llvm_anyvector_ty], [], [IntrNoMem]>; diff --git a/llvm/test/CodeGen/X86/peephole-nofold-tpoff-x86.mir b/llvm/test/CodeGen/X86/peephole-nofold-tpoff-x86.mir index 8d03401df9cfd..6dce371138e94 100644 --- a/llvm/test/CodeGen/X86/peephole-nofold-tpoff-x86.mir +++ b/llvm/test/CodeGen/X86/peephole-nofold-tpoff-x86.mir @@ -33,7 +33,7 @@ } ; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn - declare ptr @llvm.threadlocal.address.p0(ptr) #0 + declare nonnull ptr @llvm.threadlocal.address.p0(ptr nonnull) #0 attributes #0 = { nocallback nofree nosync nounwind readnone speculatable willreturn } diff --git a/llvm/test/CodeGen/X86/peephole-nofold-tpoff-x86_64.mir b/llvm/test/CodeGen/X86/peephole-nofold-tpoff-x86_64.mir index dadd1be16c5b9..afc9ff5374de5 100644 --- a/llvm/test/CodeGen/X86/peephole-nofold-tpoff-x86_64.mir +++ b/llvm/test/CodeGen/X86/peephole-nofold-tpoff-x86_64.mir @@ -23,7 +23,7 @@ } ; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn - declare ptr @llvm.threadlocal.address.p0(ptr) #0 + declare nonnull ptr @llvm.threadlocal.address.p0(ptr nonnull) #0 attributes #0 = { nocallback nofree nosync nounwind readnone speculatable willreturn } diff --git a/llvm/test/CodeGen/X86/threadlocal_address.ll b/llvm/test/CodeGen/X86/threadlocal_address.ll index 7a641c7773b6f..82597c08a4bb0 100644 --- a/llvm/test/CodeGen/X86/threadlocal_address.ll +++ b/llvm/test/CodeGen/X86/threadlocal_address.ll @@ -37,5 +37,5 @@ entry: ret i32 %3 } -declare ptr @llvm.threadlocal.address(ptr) nounwind readnone willreturn -declare ptr addrspace(1) @llvm.threadlocal.address.p1(ptr addrspace(1)) nounwind readnone willreturn +declare nonnull ptr @llvm.threadlocal.address(ptr nonnull) nounwind readnone willreturn +declare nonnull ptr addrspace(1) @llvm.threadlocal.address.p1(ptr addrspace(1) nonnull) nounwind readnone willreturn diff --git a/llvm/utils/TableGen/CodeGenIntrinsics.h b/llvm/utils/TableGen/CodeGenIntrinsics.h index 599795e3c065b..fe595058f6190 100644 --- a/llvm/utils/TableGen/CodeGenIntrinsics.h +++ b/llvm/utils/TableGen/CodeGenIntrinsics.h @@ -154,6 +154,7 @@ struct CodeGenIntrinsic { NoCapture, NoAlias, NoUndef, + NonNull, Returned, ReadOnly, WriteOnly, diff --git a/llvm/utils/TableGen/CodeGenTarget.cpp b/llvm/utils/TableGen/CodeGenTarget.cpp index af2e8576af2e5..0962f7c099a0c 100644 --- a/llvm/utils/TableGen/CodeGenTarget.cpp +++ b/llvm/utils/TableGen/CodeGenTarget.cpp @@ -893,6 +893,9 @@ void CodeGenIntrinsic::setProperty(Record *R) { } else if (R->isSubClassOf("NoUndef")) { unsigned ArgNo = R->getValueAsInt("ArgNo"); ArgumentAttributes.emplace_back(ArgNo, NoUndef, 0); + } else if (R->isSubClassOf("NonNull")) { + unsigned ArgNo = R->getValueAsInt("ArgNo"); + ArgumentAttributes.emplace_back(ArgNo, NonNull, 0); } else if (R->isSubClassOf("Returned")) { unsigned ArgNo = R->getValueAsInt("ArgNo"); ArgumentAttributes.emplace_back(ArgNo, Returned, 0); diff --git a/llvm/utils/TableGen/IntrinsicEmitter.cpp b/llvm/utils/TableGen/IntrinsicEmitter.cpp index 099f99e8e97c5..4436faea7eb5e 100644 --- a/llvm/utils/TableGen/IntrinsicEmitter.cpp +++ b/llvm/utils/TableGen/IntrinsicEmitter.cpp @@ -700,11 +700,13 @@ void IntrinsicEmitter::EmitAttributes(const CodeGenIntrinsicTable &Ints, unsigned numAttrs = 0; // The argument attributes are alreadys sorted by argument index. + assert(is_sorted(Intrinsic.ArgumentAttributes) && + "Argument attributes are not sorted"); + unsigned Ai = 0, Ae = Intrinsic.ArgumentAttributes.size(); if (Ae) { while (Ai != Ae) { unsigned AttrIdx = Intrinsic.ArgumentAttributes[Ai].Index; - OS << " const Attribute::AttrKind AttrParam" << AttrIdx << "[]= {"; ListSeparator LS(","); @@ -721,6 +723,9 @@ void IntrinsicEmitter::EmitAttributes(const CodeGenIntrinsicTable &Ints, case CodeGenIntrinsic::NoUndef: OS << LS << "Attribute::NoUndef"; break; + case CodeGenIntrinsic::NonNull: + OS << LS << "Attribute::NonNull"; + break; case CodeGenIntrinsic::Returned: OS << LS << "Attribute::Returned"; break; @@ -756,7 +761,8 @@ void IntrinsicEmitter::EmitAttributes(const CodeGenIntrinsicTable &Ints, OS << LSV << V; OS << "};\n"; } - + // AttributeList::ReturnIndex = 0, AttrParam0 corresponds to return + // value. OS << " AS[" << numAttrs++ << "] = AttributeList::get(C, " << AttrIdx << ", AttrParam" << AttrIdx; if (!AllValuesAreZero) _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits