aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/Attributes.cpp
diff options
context:
space:
mode:
authorJohannes Doerfert <johannes@jdoerfert.de>2022-02-14 17:12:34 -0600
committerJohannes Doerfert <johannes@jdoerfert.de>2022-03-28 20:57:52 -0500
commitbb0b23174e4ab963df427393fbf21bddede499bf (patch)
treee3ef9089d5607d079cdb9525a4b8e4eb1b807e5d /llvm/lib/IR/Attributes.cpp
parent662b9fa02ca217f91e683f456d70fccc7746d31c (diff)
downloadllvm-bb0b23174e4ab963df427393fbf21bddede499bf.zip
llvm-bb0b23174e4ab963df427393fbf21bddede499bf.tar.gz
llvm-bb0b23174e4ab963df427393fbf21bddede499bf.tar.bz2
[InstCombineCalls] Optimize call of bitcast even w/ parameter attributes
Before we gave up if a call through bitcast had parameter attributes. Interestingly, we allowed attributes for the return value already. We now handle both the same way, namely, we drop the ones that are incompatible with the new type and keep the rest. This cannot cause "more UB" than initially present. Differential Revision: https://reviews.llvm.org/D119967
Diffstat (limited to 'llvm/lib/IR/Attributes.cpp')
-rw-r--r--llvm/lib/IR/Attributes.cpp62
1 files changed, 36 insertions, 26 deletions
diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp
index 767767c..c4759f8 100644
--- a/llvm/lib/IR/Attributes.cpp
+++ b/llvm/lib/IR/Attributes.cpp
@@ -1773,40 +1773,50 @@ bool AttrBuilder::operator==(const AttrBuilder &B) const {
//===----------------------------------------------------------------------===//
/// Which attributes cannot be applied to a type.
-AttributeMask AttributeFuncs::typeIncompatible(Type *Ty) {
+AttributeMask AttributeFuncs::typeIncompatible(Type *Ty,
+ AttributeSafetyKind ASK) {
AttributeMask Incompatible;
- if (!Ty->isIntegerTy())
+ if (!Ty->isIntegerTy()) {
// Attributes that only apply to integers.
- Incompatible.addAttribute(Attribute::SExt)
- .addAttribute(Attribute::ZExt)
- .addAttribute(Attribute::AllocAlign);
+ if (ASK & ASK_SAFE_TO_DROP)
+ Incompatible.addAttribute(Attribute::AllocAlign);
+ if (ASK & ASK_UNSAFE_TO_DROP)
+ Incompatible.addAttribute(Attribute::SExt).addAttribute(Attribute::ZExt);
+ }
- if (!Ty->isPointerTy())
+ if (!Ty->isPointerTy()) {
// Attributes that only apply to pointers.
- Incompatible.addAttribute(Attribute::Nest)
- .addAttribute(Attribute::NoAlias)
- .addAttribute(Attribute::NoCapture)
- .addAttribute(Attribute::NonNull)
- .addAttribute(Attribute::ReadNone)
- .addAttribute(Attribute::ReadOnly)
- .addAttribute(Attribute::SwiftError)
- .addAttribute(Attribute::Dereferenceable)
- .addAttribute(Attribute::DereferenceableOrNull)
- .addAttribute(Attribute::Preallocated)
- .addAttribute(Attribute::InAlloca)
- .addAttribute(Attribute::ByVal)
- .addAttribute(Attribute::StructRet)
- .addAttribute(Attribute::ByRef)
- .addAttribute(Attribute::ElementType);
-
- if (!Ty->isPtrOrPtrVectorTy())
+ if (ASK & ASK_SAFE_TO_DROP)
+ Incompatible.addAttribute(Attribute::NoAlias)
+ .addAttribute(Attribute::NoCapture)
+ .addAttribute(Attribute::NonNull)
+ .addAttribute(Attribute::ReadNone)
+ .addAttribute(Attribute::ReadOnly)
+ .addAttribute(Attribute::Dereferenceable)
+ .addAttribute(Attribute::DereferenceableOrNull);
+ if (ASK & ASK_UNSAFE_TO_DROP)
+ Incompatible.addAttribute(Attribute::Nest)
+ .addAttribute(Attribute::SwiftError)
+ .addAttribute(Attribute::Preallocated)
+ .addAttribute(Attribute::InAlloca)
+ .addAttribute(Attribute::ByVal)
+ .addAttribute(Attribute::StructRet)
+ .addAttribute(Attribute::ByRef)
+ .addAttribute(Attribute::ElementType);
+ }
+
// Attributes that only apply to pointers or vectors of pointers.
- Incompatible.addAttribute(Attribute::Alignment);
+ if (!Ty->isPtrOrPtrVectorTy()) {
+ if (ASK & ASK_SAFE_TO_DROP)
+ Incompatible.addAttribute(Attribute::Alignment);
+ }
// Some attributes can apply to all "values" but there are no `void` values.
- if (Ty->isVoidTy())
- Incompatible.addAttribute(Attribute::NoUndef);
+ if (Ty->isVoidTy()) {
+ if (ASK & ASK_SAFE_TO_DROP)
+ Incompatible.addAttribute(Attribute::NoUndef);
+ }
return Incompatible;
}