summaryrefslogtreecommitdiff
path: root/lib/IR/Constants.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/IR/Constants.cpp')
-rw-r--r--lib/IR/Constants.cpp56
1 files changed, 39 insertions, 17 deletions
diff --git a/lib/IR/Constants.cpp b/lib/IR/Constants.cpp
index ff551da29ae6..f792f01efc1a 100644
--- a/lib/IR/Constants.cpp
+++ b/lib/IR/Constants.cpp
@@ -22,6 +22,7 @@
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Operator.h"
+#include "llvm/IR/PatternMatch.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ManagedStatic.h"
@@ -250,6 +251,20 @@ bool Constant::isNaN() const {
return true;
}
+bool Constant::isElementWiseEqual(Value *Y) const {
+ // Are they fully identical?
+ if (this == Y)
+ return true;
+ // They may still be identical element-wise (if they have `undef`s).
+ auto *Cy = dyn_cast<Constant>(Y);
+ if (!Cy)
+ return false;
+ return PatternMatch::match(ConstantExpr::getICmp(ICmpInst::Predicate::ICMP_EQ,
+ const_cast<Constant *>(this),
+ Cy),
+ PatternMatch::m_One());
+}
+
bool Constant::containsUndefElement() const {
if (!getType()->isVectorTy())
return false;
@@ -502,22 +517,32 @@ bool Constant::needsRelocation() const {
if (const BlockAddress *BA = dyn_cast<BlockAddress>(this))
return BA->getFunction()->needsRelocation();
- // While raw uses of blockaddress need to be relocated, differences between
- // two of them don't when they are for labels in the same function. This is a
- // common idiom when creating a table for the indirect goto extension, so we
- // handle it efficiently here.
- if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(this))
+ if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(this)) {
if (CE->getOpcode() == Instruction::Sub) {
ConstantExpr *LHS = dyn_cast<ConstantExpr>(CE->getOperand(0));
ConstantExpr *RHS = dyn_cast<ConstantExpr>(CE->getOperand(1));
if (LHS && RHS && LHS->getOpcode() == Instruction::PtrToInt &&
- RHS->getOpcode() == Instruction::PtrToInt &&
- isa<BlockAddress>(LHS->getOperand(0)) &&
- isa<BlockAddress>(RHS->getOperand(0)) &&
- cast<BlockAddress>(LHS->getOperand(0))->getFunction() ==
- cast<BlockAddress>(RHS->getOperand(0))->getFunction())
- return false;
+ RHS->getOpcode() == Instruction::PtrToInt) {
+ Constant *LHSOp0 = LHS->getOperand(0);
+ Constant *RHSOp0 = RHS->getOperand(0);
+
+ // While raw uses of blockaddress need to be relocated, differences
+ // between two of them don't when they are for labels in the same
+ // function. This is a common idiom when creating a table for the
+ // indirect goto extension, so we handle it efficiently here.
+ if (isa<BlockAddress>(LHSOp0) && isa<BlockAddress>(RHSOp0) &&
+ cast<BlockAddress>(LHSOp0)->getFunction() ==
+ cast<BlockAddress>(RHSOp0)->getFunction())
+ return false;
+
+ // Relative pointers do not need to be dynamically relocated.
+ if (auto *LHSGV = dyn_cast<GlobalValue>(LHSOp0->stripPointerCasts()))
+ if (auto *RHSGV = dyn_cast<GlobalValue>(RHSOp0->stripPointerCasts()))
+ if (LHSGV->isDSOLocal() && RHSGV->isDSOLocal())
+ return false;
+ }
}
+ }
bool Result = false;
for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
@@ -563,13 +588,10 @@ void Constant::removeDeadConstantUsers() const {
}
// If the constant was dead, then the iterator is invalidated.
- if (LastNonDeadUser == E) {
+ if (LastNonDeadUser == E)
I = user_begin();
- if (I == E) break;
- } else {
- I = LastNonDeadUser;
- ++I;
- }
+ else
+ I = std::next(LastNonDeadUser);
}
}