-
Notifications
You must be signed in to change notification settings - Fork 14.3k
Take poison-generating attributes into account #89138
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…ibute (NFC) These are currently being miscompiled.
@llvm/pr-subscribers-llvm-ir @llvm/pr-subscribers-llvm-analysis Author: Andreas Jonson (andjo403) ChangesSplit out and fixed comments from #88776 CC @nikic Full diff: https://github.com/llvm/llvm-project/pull/89138.diff 14 Files Affected:
diff --git a/llvm/include/llvm/IR/Instruction.h b/llvm/include/llvm/IR/Instruction.h
index 6e0874c5b04f29..0c6c16eb61dd3f 100644
--- a/llvm/include/llvm/IR/Instruction.h
+++ b/llvm/include/llvm/IR/Instruction.h
@@ -496,14 +496,23 @@ class Instruction : public User,
/// Drops metadata that may generate poison.
void dropPoisonGeneratingMetadata();
- /// Return true if this instruction has poison-generating flags or metadata.
- bool hasPoisonGeneratingFlagsOrMetadata() const {
- return hasPoisonGeneratingFlags() || hasPoisonGeneratingMetadata();
+ /// Return true if this instruction has poison-generating attribute.
+ bool hasPoisonGeneratingAttribute() const LLVM_READONLY;
+
+ /// Drops attributes that may generate poison.
+ void dropPoisonGeneratingAttribute();
+
+ /// Return true if this instruction has poison-generating flags, attributes or
+ /// metadata.
+ bool hasPoisonGeneratingAnnotations() const {
+ return hasPoisonGeneratingFlags() || hasPoisonGeneratingAttribute() ||
+ hasPoisonGeneratingMetadata();
}
- /// Drops flags and metadata that may generate poison.
- void dropPoisonGeneratingFlagsAndMetadata() {
+ /// Drops flags, attributes and metadata that may generate poison.
+ void dropPoisonGeneratingAnnotations() {
dropPoisonGeneratingFlags();
+ dropPoisonGeneratingAttribute();
dropPoisonGeneratingMetadata();
}
diff --git a/llvm/include/llvm/IR/Operator.h b/llvm/include/llvm/IR/Operator.h
index e14a916b474935..860f10adab005d 100644
--- a/llvm/include/llvm/IR/Operator.h
+++ b/llvm/include/llvm/IR/Operator.h
@@ -64,9 +64,9 @@ class Operator : public User {
/// to evaluate to poison despite having non-poison inputs.
bool hasPoisonGeneratingFlags() const;
- /// Return true if this operator has poison-generating flags or metadata.
- /// The latter is only possible for instructions.
- bool hasPoisonGeneratingFlagsOrMetadata() const;
+ /// Return true if this operator has poison-generating flags, attributes or
+ /// metadata. The latter two is only possible for instructions.
+ bool hasPoisonGeneratingAnnotations() const;
};
/// Utility class for integer operators which may exhibit overflow - Add, Sub,
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 06ba5ca4c6b352..431ad37d0a9e86 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -4431,7 +4431,7 @@ static Value *simplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
return nullptr;
}
Constant *Res = ConstantFoldInstOperands(I, ConstOps, Q.DL, Q.TLI);
- if (DropFlags && Res && I->hasPoisonGeneratingFlagsOrMetadata())
+ if (DropFlags && Res && I->hasPoisonGeneratingAnnotations())
DropFlags->push_back(I);
return Res;
}
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 95440dda3b4c0e..93f885c5d5ad8b 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -4239,7 +4239,7 @@ bool ScalarEvolution::canReuseInstruction(
return false;
// If the instruction can't create poison, we can recurse to its operands.
- if (I->hasPoisonGeneratingFlagsOrMetadata())
+ if (I->hasPoisonGeneratingAnnotations())
DropPoisonGeneratingInsts.push_back(I);
for (Value *Op : I->operands())
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index ab2f43e1033fa1..695d0b0b1a2f87 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -6951,7 +6951,7 @@ static bool canCreateUndefOrPoison(const Operator *Op, UndefPoisonKind Kind,
bool ConsiderFlagsAndMetadata) {
if (ConsiderFlagsAndMetadata && includesPoison(Kind) &&
- Op->hasPoisonGeneratingFlagsOrMetadata())
+ Op->hasPoisonGeneratingAnnotations())
return true;
unsigned Opcode = Op->getOpcode();
diff --git a/llvm/lib/IR/Instruction.cpp b/llvm/lib/IR/Instruction.cpp
index b9efe9cdcfe310..4df5ee63ac183c 100644
--- a/llvm/lib/IR/Instruction.cpp
+++ b/llvm/lib/IR/Instruction.cpp
@@ -13,7 +13,9 @@
#include "llvm/IR/Instruction.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/IR/AttributeMask.h"
+#include "llvm/IR/Attributes.h"
#include "llvm/IR/Constants.h"
+#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
@@ -472,6 +474,27 @@ void Instruction::dropPoisonGeneratingMetadata() {
eraseMetadata(LLVMContext::MD_align);
}
+bool Instruction::hasPoisonGeneratingAttribute() const {
+ if (const auto *CB = dyn_cast<CallBase>(this)) {
+ AttributeSet RetAttrs = CB->getAttributes().getRetAttrs();
+ return RetAttrs.hasAttribute(Attribute::Range) ||
+ RetAttrs.hasAttribute(Attribute::Alignment) ||
+ RetAttrs.hasAttribute(Attribute::NonNull);
+ }
+ return false;
+}
+
+void Instruction::dropPoisonGeneratingAttribute() {
+ if (auto *CB = dyn_cast<CallBase>(this)) {
+ AttributeMask AM;
+ AM.addAttribute(Attribute::Range);
+ AM.addAttribute(Attribute::Alignment);
+ AM.addAttribute(Attribute::NonNull);
+ CB->removeRetAttrs(AM);
+ }
+ assert(!hasPoisonGeneratingAttribute() && "must be kept in sync");
+}
+
void Instruction::dropUBImplyingAttrsAndUnknownMetadata(
ArrayRef<unsigned> KnownIDs) {
dropUnknownNonDebugMetadata(KnownIDs);
diff --git a/llvm/lib/IR/Operator.cpp b/llvm/lib/IR/Operator.cpp
index ccc624d854429c..eeefd4178ce37d 100644
--- a/llvm/lib/IR/Operator.cpp
+++ b/llvm/lib/IR/Operator.cpp
@@ -56,11 +56,12 @@ bool Operator::hasPoisonGeneratingFlags() const {
}
}
-bool Operator::hasPoisonGeneratingFlagsOrMetadata() const {
+bool Operator::hasPoisonGeneratingAnnotations() const {
if (hasPoisonGeneratingFlags())
return true;
auto *I = dyn_cast<Instruction>(this);
- return I && I->hasPoisonGeneratingMetadata();
+ return I && (I->hasPoisonGeneratingAttribute() ||
+ I->hasPoisonGeneratingMetadata());
}
Type *GEPOperator::getSourceElementType() const {
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 2d78fcee1152d7..9f6a4b2f395987 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -1340,7 +1340,7 @@ Instruction *InstCombinerImpl::foldSelectValueEquivalence(SelectInst &Sel,
/* AllowRefinement */ false,
&DropFlags) == TrueVal) {
for (Instruction *I : DropFlags) {
- I->dropPoisonGeneratingFlagsAndMetadata();
+ I->dropPoisonGeneratingAnnotations();
Worklist.add(I);
}
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index 5a144cc7378962..e08d0a80e76536 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -4330,7 +4330,7 @@ InstCombinerImpl::pushFreezeToPreventPoisonFromPropagating(FreezeInst &OrigFI) {
return nullptr;
}
- OrigOpInst->dropPoisonGeneratingFlagsAndMetadata();
+ OrigOpInst->dropPoisonGeneratingAnnotations();
// If all operands are guaranteed to be non-poison, we can drop freeze.
if (!MaybePoisonOperand)
@@ -4401,7 +4401,7 @@ Instruction *InstCombinerImpl::foldFreezeIntoRecurrence(FreezeInst &FI,
}
for (Instruction *I : DropFlags)
- I->dropPoisonGeneratingFlagsAndMetadata();
+ I->dropPoisonGeneratingAnnotations();
if (StartNeedsFreeze) {
Builder.SetInsertPoint(StartBB->getTerminator());
diff --git a/llvm/lib/Transforms/Scalar/BDCE.cpp b/llvm/lib/Transforms/Scalar/BDCE.cpp
index 4aa87a84f115a1..d96dbca30fdb15 100644
--- a/llvm/lib/Transforms/Scalar/BDCE.cpp
+++ b/llvm/lib/Transforms/Scalar/BDCE.cpp
@@ -75,7 +75,7 @@ static void clearAssumptionsOfUsers(Instruction *I, DemandedBits &DB) {
Instruction *J = WorkList.pop_back_val();
// NSW, NUW, and exact are based on operands that might have changed.
- J->dropPoisonGeneratingFlagsAndMetadata();
+ J->dropPoisonGeneratingAnnotations();
// We do not have to worry about llvm.assume, because it demands its
// operand, so trivializing can't change it.
diff --git a/llvm/lib/Transforms/Scalar/GuardWidening.cpp b/llvm/lib/Transforms/Scalar/GuardWidening.cpp
index d3787b28347c9e..b6498c4e36963a 100644
--- a/llvm/lib/Transforms/Scalar/GuardWidening.cpp
+++ b/llvm/lib/Transforms/Scalar/GuardWidening.cpp
@@ -699,7 +699,7 @@ Value *GuardWideningImpl::freezeAndPush(Value *Orig,
Worklist.push_back(U.get());
}
for (Instruction *I : DropPoisonFlags)
- I->dropPoisonGeneratingFlagsAndMetadata();
+ I->dropPoisonGeneratingAnnotations();
Value *Result = Orig;
for (Value *V : NeedFreeze) {
diff --git a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
index 74cffbc005c82d..0feea0a4233cd1 100644
--- a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
+++ b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
@@ -1522,7 +1522,7 @@ Value *SCEVExpander::expand(const SCEV *S) {
} else {
for (Instruction *I : DropPoisonGeneratingInsts) {
rememberFlags(I);
- I->dropPoisonGeneratingFlagsAndMetadata();
+ I->dropPoisonGeneratingAnnotations();
// See if we can re-infer from first principles any of the flags we just
// dropped.
if (auto *OBO = dyn_cast<OverflowingBinaryOperator>(I))
diff --git a/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp b/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
index 31be7d62c8d1d8..912c02c2ed3ae5 100644
--- a/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
@@ -768,7 +768,7 @@ bool SimplifyIndvar::eliminateIdentitySCEV(Instruction *UseInst,
return false;
for (Instruction *I : DropPoisonGeneratingInsts)
- I->dropPoisonGeneratingFlagsAndMetadata();
+ I->dropPoisonGeneratingAnnotations();
}
LLVM_DEBUG(dbgs() << "INDVARS: Eliminated identity: " << *UseInst << '\n');
diff --git a/llvm/test/Transforms/InstCombine/freeze.ll b/llvm/test/Transforms/InstCombine/freeze.ll
index 668f3033ed4b73..adcf7d50f413be 100644
--- a/llvm/test/Transforms/InstCombine/freeze.ll
+++ b/llvm/test/Transforms/InstCombine/freeze.ll
@@ -1069,7 +1069,7 @@ define ptr @freeze_load_dereferenceable(ptr %ptr) {
define ptr @freeze_load_dereferenceable_or_null(ptr %ptr) {
; CHECK-LABEL: @freeze_load_dereferenceable_or_null(
-; CHECK-NEXT: [[P:%.*]] = load ptr, ptr [[PTR:%.*]], align 8, !dereferenceable_or_null !1
+; CHECK-NEXT: [[P:%.*]] = load ptr, ptr [[PTR:%.*]], align 8, !dereferenceable_or_null [[META1]]
; CHECK-NEXT: ret ptr [[P]]
;
%p = load ptr, ptr %ptr, !dereferenceable_or_null !1
@@ -1160,6 +1160,45 @@ define i32 @propagate_drop_flags_trunc(i64 %arg) {
ret i32 %v1.fr
}
+declare i32 @llvm.umax.i32(i32 %a, i32 %b)
+
+define i32 @freeze_call_with_range_attr(i32 %a) {
+; CHECK-LABEL: @freeze_call_with_range_attr(
+; CHECK-NEXT: [[Y:%.*]] = lshr i32 2047, [[A:%.*]]
+; CHECK-NEXT: [[Y_FR:%.*]] = freeze i32 [[Y]]
+; CHECK-NEXT: [[X:%.*]] = call i32 @llvm.umax.i32(i32 [[Y_FR]], i32 50)
+; CHECK-NEXT: ret i32 [[X]]
+;
+ %y = lshr i32 2047, %a
+ %x = call range(i32 0, 2048) i32 @llvm.umax.i32(i32 %y, i32 50)
+ %x.fr = freeze i32 %x
+ ret i32 %x.fr
+}
+
+declare ptr @llvm.ptrmask.p0.i64(ptr, i64)
+
+define ptr @freeze_ptrmask_align(ptr %p, i64 noundef %m) {
+; CHECK-LABEL: @freeze_ptrmask_align(
+; CHECK-NEXT: [[P_FR:%.*]] = freeze ptr [[P:%.*]]
+; CHECK-NEXT: [[MASK:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[P_FR]], i64 [[M:%.*]])
+; CHECK-NEXT: ret ptr [[MASK]]
+;
+ %mask = call align(4) ptr @llvm.ptrmask.p0.i64(ptr %p, i64 %m)
+ %fr = freeze ptr %mask
+ ret ptr %fr
+}
+
+define ptr @freeze_ptrmask_nonnull(ptr %p, i64 noundef %m) {
+; CHECK-LABEL: @freeze_ptrmask_nonnull(
+; CHECK-NEXT: [[P_FR:%.*]] = freeze ptr [[P:%.*]]
+; CHECK-NEXT: [[MASK:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[P_FR]], i64 [[M:%.*]])
+; CHECK-NEXT: ret ptr [[MASK]]
+;
+ %mask = call nonnull ptr @llvm.ptrmask.p0.i64(ptr %p, i64 %m)
+ %fr = freeze ptr %mask
+ ret ptr %fr
+}
+
!0 = !{}
!1 = !{i64 4}
!2 = !{i32 0, i32 100}
|
@llvm/pr-subscribers-llvm-transforms Author: Andreas Jonson (andjo403) ChangesSplit out and fixed comments from #88776 CC @nikic Full diff: https://github.com/llvm/llvm-project/pull/89138.diff 14 Files Affected:
diff --git a/llvm/include/llvm/IR/Instruction.h b/llvm/include/llvm/IR/Instruction.h
index 6e0874c5b04f29..0c6c16eb61dd3f 100644
--- a/llvm/include/llvm/IR/Instruction.h
+++ b/llvm/include/llvm/IR/Instruction.h
@@ -496,14 +496,23 @@ class Instruction : public User,
/// Drops metadata that may generate poison.
void dropPoisonGeneratingMetadata();
- /// Return true if this instruction has poison-generating flags or metadata.
- bool hasPoisonGeneratingFlagsOrMetadata() const {
- return hasPoisonGeneratingFlags() || hasPoisonGeneratingMetadata();
+ /// Return true if this instruction has poison-generating attribute.
+ bool hasPoisonGeneratingAttribute() const LLVM_READONLY;
+
+ /// Drops attributes that may generate poison.
+ void dropPoisonGeneratingAttribute();
+
+ /// Return true if this instruction has poison-generating flags, attributes or
+ /// metadata.
+ bool hasPoisonGeneratingAnnotations() const {
+ return hasPoisonGeneratingFlags() || hasPoisonGeneratingAttribute() ||
+ hasPoisonGeneratingMetadata();
}
- /// Drops flags and metadata that may generate poison.
- void dropPoisonGeneratingFlagsAndMetadata() {
+ /// Drops flags, attributes and metadata that may generate poison.
+ void dropPoisonGeneratingAnnotations() {
dropPoisonGeneratingFlags();
+ dropPoisonGeneratingAttribute();
dropPoisonGeneratingMetadata();
}
diff --git a/llvm/include/llvm/IR/Operator.h b/llvm/include/llvm/IR/Operator.h
index e14a916b474935..860f10adab005d 100644
--- a/llvm/include/llvm/IR/Operator.h
+++ b/llvm/include/llvm/IR/Operator.h
@@ -64,9 +64,9 @@ class Operator : public User {
/// to evaluate to poison despite having non-poison inputs.
bool hasPoisonGeneratingFlags() const;
- /// Return true if this operator has poison-generating flags or metadata.
- /// The latter is only possible for instructions.
- bool hasPoisonGeneratingFlagsOrMetadata() const;
+ /// Return true if this operator has poison-generating flags, attributes or
+ /// metadata. The latter two is only possible for instructions.
+ bool hasPoisonGeneratingAnnotations() const;
};
/// Utility class for integer operators which may exhibit overflow - Add, Sub,
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 06ba5ca4c6b352..431ad37d0a9e86 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -4431,7 +4431,7 @@ static Value *simplifyWithOpReplaced(Value *V, Value *Op, Value *RepOp,
return nullptr;
}
Constant *Res = ConstantFoldInstOperands(I, ConstOps, Q.DL, Q.TLI);
- if (DropFlags && Res && I->hasPoisonGeneratingFlagsOrMetadata())
+ if (DropFlags && Res && I->hasPoisonGeneratingAnnotations())
DropFlags->push_back(I);
return Res;
}
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 95440dda3b4c0e..93f885c5d5ad8b 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -4239,7 +4239,7 @@ bool ScalarEvolution::canReuseInstruction(
return false;
// If the instruction can't create poison, we can recurse to its operands.
- if (I->hasPoisonGeneratingFlagsOrMetadata())
+ if (I->hasPoisonGeneratingAnnotations())
DropPoisonGeneratingInsts.push_back(I);
for (Value *Op : I->operands())
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index ab2f43e1033fa1..695d0b0b1a2f87 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -6951,7 +6951,7 @@ static bool canCreateUndefOrPoison(const Operator *Op, UndefPoisonKind Kind,
bool ConsiderFlagsAndMetadata) {
if (ConsiderFlagsAndMetadata && includesPoison(Kind) &&
- Op->hasPoisonGeneratingFlagsOrMetadata())
+ Op->hasPoisonGeneratingAnnotations())
return true;
unsigned Opcode = Op->getOpcode();
diff --git a/llvm/lib/IR/Instruction.cpp b/llvm/lib/IR/Instruction.cpp
index b9efe9cdcfe310..4df5ee63ac183c 100644
--- a/llvm/lib/IR/Instruction.cpp
+++ b/llvm/lib/IR/Instruction.cpp
@@ -13,7 +13,9 @@
#include "llvm/IR/Instruction.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/IR/AttributeMask.h"
+#include "llvm/IR/Attributes.h"
#include "llvm/IR/Constants.h"
+#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
@@ -472,6 +474,27 @@ void Instruction::dropPoisonGeneratingMetadata() {
eraseMetadata(LLVMContext::MD_align);
}
+bool Instruction::hasPoisonGeneratingAttribute() const {
+ if (const auto *CB = dyn_cast<CallBase>(this)) {
+ AttributeSet RetAttrs = CB->getAttributes().getRetAttrs();
+ return RetAttrs.hasAttribute(Attribute::Range) ||
+ RetAttrs.hasAttribute(Attribute::Alignment) ||
+ RetAttrs.hasAttribute(Attribute::NonNull);
+ }
+ return false;
+}
+
+void Instruction::dropPoisonGeneratingAttribute() {
+ if (auto *CB = dyn_cast<CallBase>(this)) {
+ AttributeMask AM;
+ AM.addAttribute(Attribute::Range);
+ AM.addAttribute(Attribute::Alignment);
+ AM.addAttribute(Attribute::NonNull);
+ CB->removeRetAttrs(AM);
+ }
+ assert(!hasPoisonGeneratingAttribute() && "must be kept in sync");
+}
+
void Instruction::dropUBImplyingAttrsAndUnknownMetadata(
ArrayRef<unsigned> KnownIDs) {
dropUnknownNonDebugMetadata(KnownIDs);
diff --git a/llvm/lib/IR/Operator.cpp b/llvm/lib/IR/Operator.cpp
index ccc624d854429c..eeefd4178ce37d 100644
--- a/llvm/lib/IR/Operator.cpp
+++ b/llvm/lib/IR/Operator.cpp
@@ -56,11 +56,12 @@ bool Operator::hasPoisonGeneratingFlags() const {
}
}
-bool Operator::hasPoisonGeneratingFlagsOrMetadata() const {
+bool Operator::hasPoisonGeneratingAnnotations() const {
if (hasPoisonGeneratingFlags())
return true;
auto *I = dyn_cast<Instruction>(this);
- return I && I->hasPoisonGeneratingMetadata();
+ return I && (I->hasPoisonGeneratingAttribute() ||
+ I->hasPoisonGeneratingMetadata());
}
Type *GEPOperator::getSourceElementType() const {
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 2d78fcee1152d7..9f6a4b2f395987 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -1340,7 +1340,7 @@ Instruction *InstCombinerImpl::foldSelectValueEquivalence(SelectInst &Sel,
/* AllowRefinement */ false,
&DropFlags) == TrueVal) {
for (Instruction *I : DropFlags) {
- I->dropPoisonGeneratingFlagsAndMetadata();
+ I->dropPoisonGeneratingAnnotations();
Worklist.add(I);
}
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index 5a144cc7378962..e08d0a80e76536 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -4330,7 +4330,7 @@ InstCombinerImpl::pushFreezeToPreventPoisonFromPropagating(FreezeInst &OrigFI) {
return nullptr;
}
- OrigOpInst->dropPoisonGeneratingFlagsAndMetadata();
+ OrigOpInst->dropPoisonGeneratingAnnotations();
// If all operands are guaranteed to be non-poison, we can drop freeze.
if (!MaybePoisonOperand)
@@ -4401,7 +4401,7 @@ Instruction *InstCombinerImpl::foldFreezeIntoRecurrence(FreezeInst &FI,
}
for (Instruction *I : DropFlags)
- I->dropPoisonGeneratingFlagsAndMetadata();
+ I->dropPoisonGeneratingAnnotations();
if (StartNeedsFreeze) {
Builder.SetInsertPoint(StartBB->getTerminator());
diff --git a/llvm/lib/Transforms/Scalar/BDCE.cpp b/llvm/lib/Transforms/Scalar/BDCE.cpp
index 4aa87a84f115a1..d96dbca30fdb15 100644
--- a/llvm/lib/Transforms/Scalar/BDCE.cpp
+++ b/llvm/lib/Transforms/Scalar/BDCE.cpp
@@ -75,7 +75,7 @@ static void clearAssumptionsOfUsers(Instruction *I, DemandedBits &DB) {
Instruction *J = WorkList.pop_back_val();
// NSW, NUW, and exact are based on operands that might have changed.
- J->dropPoisonGeneratingFlagsAndMetadata();
+ J->dropPoisonGeneratingAnnotations();
// We do not have to worry about llvm.assume, because it demands its
// operand, so trivializing can't change it.
diff --git a/llvm/lib/Transforms/Scalar/GuardWidening.cpp b/llvm/lib/Transforms/Scalar/GuardWidening.cpp
index d3787b28347c9e..b6498c4e36963a 100644
--- a/llvm/lib/Transforms/Scalar/GuardWidening.cpp
+++ b/llvm/lib/Transforms/Scalar/GuardWidening.cpp
@@ -699,7 +699,7 @@ Value *GuardWideningImpl::freezeAndPush(Value *Orig,
Worklist.push_back(U.get());
}
for (Instruction *I : DropPoisonFlags)
- I->dropPoisonGeneratingFlagsAndMetadata();
+ I->dropPoisonGeneratingAnnotations();
Value *Result = Orig;
for (Value *V : NeedFreeze) {
diff --git a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
index 74cffbc005c82d..0feea0a4233cd1 100644
--- a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
+++ b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
@@ -1522,7 +1522,7 @@ Value *SCEVExpander::expand(const SCEV *S) {
} else {
for (Instruction *I : DropPoisonGeneratingInsts) {
rememberFlags(I);
- I->dropPoisonGeneratingFlagsAndMetadata();
+ I->dropPoisonGeneratingAnnotations();
// See if we can re-infer from first principles any of the flags we just
// dropped.
if (auto *OBO = dyn_cast<OverflowingBinaryOperator>(I))
diff --git a/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp b/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
index 31be7d62c8d1d8..912c02c2ed3ae5 100644
--- a/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
@@ -768,7 +768,7 @@ bool SimplifyIndvar::eliminateIdentitySCEV(Instruction *UseInst,
return false;
for (Instruction *I : DropPoisonGeneratingInsts)
- I->dropPoisonGeneratingFlagsAndMetadata();
+ I->dropPoisonGeneratingAnnotations();
}
LLVM_DEBUG(dbgs() << "INDVARS: Eliminated identity: " << *UseInst << '\n');
diff --git a/llvm/test/Transforms/InstCombine/freeze.ll b/llvm/test/Transforms/InstCombine/freeze.ll
index 668f3033ed4b73..adcf7d50f413be 100644
--- a/llvm/test/Transforms/InstCombine/freeze.ll
+++ b/llvm/test/Transforms/InstCombine/freeze.ll
@@ -1069,7 +1069,7 @@ define ptr @freeze_load_dereferenceable(ptr %ptr) {
define ptr @freeze_load_dereferenceable_or_null(ptr %ptr) {
; CHECK-LABEL: @freeze_load_dereferenceable_or_null(
-; CHECK-NEXT: [[P:%.*]] = load ptr, ptr [[PTR:%.*]], align 8, !dereferenceable_or_null !1
+; CHECK-NEXT: [[P:%.*]] = load ptr, ptr [[PTR:%.*]], align 8, !dereferenceable_or_null [[META1]]
; CHECK-NEXT: ret ptr [[P]]
;
%p = load ptr, ptr %ptr, !dereferenceable_or_null !1
@@ -1160,6 +1160,45 @@ define i32 @propagate_drop_flags_trunc(i64 %arg) {
ret i32 %v1.fr
}
+declare i32 @llvm.umax.i32(i32 %a, i32 %b)
+
+define i32 @freeze_call_with_range_attr(i32 %a) {
+; CHECK-LABEL: @freeze_call_with_range_attr(
+; CHECK-NEXT: [[Y:%.*]] = lshr i32 2047, [[A:%.*]]
+; CHECK-NEXT: [[Y_FR:%.*]] = freeze i32 [[Y]]
+; CHECK-NEXT: [[X:%.*]] = call i32 @llvm.umax.i32(i32 [[Y_FR]], i32 50)
+; CHECK-NEXT: ret i32 [[X]]
+;
+ %y = lshr i32 2047, %a
+ %x = call range(i32 0, 2048) i32 @llvm.umax.i32(i32 %y, i32 50)
+ %x.fr = freeze i32 %x
+ ret i32 %x.fr
+}
+
+declare ptr @llvm.ptrmask.p0.i64(ptr, i64)
+
+define ptr @freeze_ptrmask_align(ptr %p, i64 noundef %m) {
+; CHECK-LABEL: @freeze_ptrmask_align(
+; CHECK-NEXT: [[P_FR:%.*]] = freeze ptr [[P:%.*]]
+; CHECK-NEXT: [[MASK:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[P_FR]], i64 [[M:%.*]])
+; CHECK-NEXT: ret ptr [[MASK]]
+;
+ %mask = call align(4) ptr @llvm.ptrmask.p0.i64(ptr %p, i64 %m)
+ %fr = freeze ptr %mask
+ ret ptr %fr
+}
+
+define ptr @freeze_ptrmask_nonnull(ptr %p, i64 noundef %m) {
+; CHECK-LABEL: @freeze_ptrmask_nonnull(
+; CHECK-NEXT: [[P_FR:%.*]] = freeze ptr [[P:%.*]]
+; CHECK-NEXT: [[MASK:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[P_FR]], i64 [[M:%.*]])
+; CHECK-NEXT: ret ptr [[MASK]]
+;
+ %mask = call nonnull ptr @llvm.ptrmask.p0.i64(ptr %p, i64 %m)
+ %fr = freeze ptr %mask
+ ret ptr %fr
+}
+
!0 = !{}
!1 = !{i64 4}
!2 = !{i32 0, i32 100}
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
llvm/include/llvm/IR/Instruction.h
Outdated
bool hasPoisonGeneratingFlagsOrMetadata() const { | ||
return hasPoisonGeneratingFlags() || hasPoisonGeneratingMetadata(); | ||
/// Return true if this instruction has poison-generating attribute. | ||
bool hasPoisonGeneratingAttribute() const LLVM_READONLY; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bool hasPoisonGeneratingAttribute() const LLVM_READONLY; | |
bool hasPoisonGeneratingReturnAttributes() const LLVM_READONLY; |
Maybe? Just to make clear this won't report these attributes in argument position.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes think that it makes it much better have fixed it now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Split out and fixed comments from #88776
CC @nikic