diff --git a/include/llvm/IR/Intrinsics.td b/include/llvm/IR/Intrinsics.td index 582fe613f75..5a4998e2212 100644 --- a/include/llvm/IR/Intrinsics.td +++ b/include/llvm/IR/Intrinsics.td @@ -134,10 +134,14 @@ def IntrWillReturn : IntrinsicProperty<1>; // Parallels the cold attribute on LLVM IR functions. def IntrCold : IntrinsicProperty; -// IntrNoduplicate - Calls to this intrinsic cannot be duplicated. +// IntrNoDuplicate - Calls to this intrinsic cannot be duplicated. // Parallels the noduplicate attribute on LLVM IR functions. def IntrNoDuplicate : IntrinsicProperty; +// IntrNoMerge - Calls to this intrinsic cannot be merged +// Parallels the nomerge attribute on LLVM IR functions. +def IntrNoMerge : IntrinsicProperty; + // IntrConvergent - Calls to this intrinsic are convergent and may not be made // control-dependent on any additional values. // Parallels the convergent attribute on LLVM IR functions. diff --git a/test/TableGen/intrin-properties.td b/test/TableGen/intrin-properties.td new file mode 100644 index 00000000000..2e2e32d54fb --- /dev/null +++ b/test/TableGen/intrin-properties.td @@ -0,0 +1,24 @@ +// RUN: sed -e 's//ArgMemOnly/;s//ArgMemOnly/' < %s > %t; llvm-tblgen -gen-intrinsic-impl -I %p/../../include %t | FileCheck %t +// RUN: sed -e 's//Cold/;s//Cold/' < %s > %t; llvm-tblgen -gen-intrinsic-impl -I %p/../../include %t | FileCheck %t +// RUN: sed -e 's//Convergent/;s//Convergent/' < %s > %t; llvm-tblgen -gen-intrinsic-impl -I %p/../../include %t | FileCheck %t +// RUN: sed -e 's//InaccessibleMemOnly/;s//InaccessibleMemOnly/' < %s > %t; llvm-tblgen -gen-intrinsic-impl -I %p/../../include %t | FileCheck %t +// RUN: sed -e 's//InaccessibleMemOrArgMemOnly/;s//InaccessibleMemOrArgMemOnly/' < %s > %t; llvm-tblgen -gen-intrinsic-impl -I %p/../../include %t | FileCheck %t +// RUN: sed -e 's//NoDuplicate/;s//NoDuplicate/' < %s > %t; llvm-tblgen -gen-intrinsic-impl -I %p/../../include %t | FileCheck %t +// RUN: sed -e 's//NoFree/;s//NoFree/' < %s > %t; llvm-tblgen -gen-intrinsic-impl -I %p/../../include %t | FileCheck %t +// RUN: sed -e 's//NoMem/;s//ReadNone/' < %s > %t; llvm-tblgen -gen-intrinsic-impl -I %p/../../include %t | FileCheck %t +// RUN: sed -e 's//NoMerge/;s//NoMerge/' < %s > %t; llvm-tblgen -gen-intrinsic-impl -I %p/../../include %t | FileCheck %t +// RUN: sed -e 's//NoReturn/;s//NoReturn/' < %s > %t; llvm-tblgen -gen-intrinsic-impl -I %p/../../include %t | FileCheck %t +// RUN: sed -e 's//NoSync/;s//NoSync/' < %s > %t; llvm-tblgen -gen-intrinsic-impl -I %p/../../include %t | FileCheck %t +// RUN: sed -e 's//ReadMem/;s//ReadOnly/' < %s > %t; llvm-tblgen -gen-intrinsic-impl -I %p/../../include %t | FileCheck %t +// RUN: sed -e 's//Speculatable/;s//Speculatable/' < %s > %t; llvm-tblgen -gen-intrinsic-impl -I %p/../../include %t | FileCheck %t +// RUN: sed -e 's//WillReturn/;s//WillReturn/' < %s > %t; llvm-tblgen -gen-intrinsic-impl -I %p/../../include %t | FileCheck %t +// RUN: sed -e 's//WriteMem/;s//WriteOnly/' < %s > %t; llvm-tblgen -gen-intrinsic-impl -I %p/../../include %t | FileCheck %t + +include "llvm/IR/Intrinsics.td" + +// CHECK: [[I:[0-9]+]], // llvm.tgtest.Intr +// CHECK: case [[I]]: +// CHECK-NEXT: Atts[] = {{.*}}Attribute:: +def int_tgtest_Intr: + Intrinsic<[llvm_i32_ty], [llvm_ptr_ty], [Intr]>; + diff --git a/utils/TableGen/CodeGenIntrinsics.h b/utils/TableGen/CodeGenIntrinsics.h index c469f662a42..dbfad3bf6b1 100644 --- a/utils/TableGen/CodeGenIntrinsics.h +++ b/utils/TableGen/CodeGenIntrinsics.h @@ -120,6 +120,9 @@ struct CodeGenIntrinsic { /// True if the intrinsic is marked as noduplicate. bool isNoDuplicate; + /// True if the intrinsic is marked as nomerge. + bool isNoMerge; + /// True if the intrinsic is no-return. bool isNoReturn; diff --git a/utils/TableGen/CodeGenTarget.cpp b/utils/TableGen/CodeGenTarget.cpp index 8f6d212df5e..2c3e4decc58 100644 --- a/utils/TableGen/CodeGenTarget.cpp +++ b/utils/TableGen/CodeGenTarget.cpp @@ -656,6 +656,7 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R, isWillReturn = false; isCold = false; isNoDuplicate = false; + isNoMerge = false; isConvergent = false; isSpeculatable = false; hasSideEffects = false; @@ -845,6 +846,8 @@ void CodeGenIntrinsic::setProperty(Record *R) { canThrow = true; else if (R->getName() == "IntrNoDuplicate") isNoDuplicate = true; + else if (R->getName() == "IntrNoMerge") + isNoMerge = true; else if (R->getName() == "IntrConvergent") isConvergent = true; else if (R->getName() == "IntrNoReturn") diff --git a/utils/TableGen/IntrinsicEmitter.cpp b/utils/TableGen/IntrinsicEmitter.cpp index 7835f644d19..aa844961b01 100644 --- a/utils/TableGen/IntrinsicEmitter.cpp +++ b/utils/TableGen/IntrinsicEmitter.cpp @@ -584,6 +584,9 @@ struct AttributeComparator { if (L->isNoDuplicate != R->isNoDuplicate) return R->isNoDuplicate; + if (L->isNoMerge != R->isNoMerge) + return R->isNoMerge; + if (L->isNoReturn != R->isNoReturn) return R->isNoReturn; @@ -739,7 +742,8 @@ void IntrinsicEmitter::EmitAttributes(const CodeGenIntrinsicTable &Ints, !intrinsic.hasSideEffects) || intrinsic.isNoReturn || intrinsic.isNoSync || intrinsic.isNoFree || intrinsic.isWillReturn || intrinsic.isCold || intrinsic.isNoDuplicate || - intrinsic.isConvergent || intrinsic.isSpeculatable) { + intrinsic.isNoMerge || intrinsic.isConvergent || + intrinsic.isSpeculatable) { OS << " const Attribute::AttrKind Atts[] = {"; ListSeparator LS(","); if (!intrinsic.canThrow) @@ -756,6 +760,8 @@ void IntrinsicEmitter::EmitAttributes(const CodeGenIntrinsicTable &Ints, OS << LS << "Attribute::Cold"; if (intrinsic.isNoDuplicate) OS << LS << "Attribute::NoDuplicate"; + if (intrinsic.isNoMerge) + OS << LS << "Attribute::NoMerge"; if (intrinsic.isConvergent) OS << LS << "Attribute::Convergent"; if (intrinsic.isSpeculatable)