summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/IR/Constants.h3
-rw-r--r--llvm/lib/IR/Constants.cpp13
-rw-r--r--llvm/lib/Transforms/Utils/ValueMapper.cpp9
3 files changed, 17 insertions, 8 deletions
diff --git a/llvm/include/llvm/IR/Constants.h b/llvm/include/llvm/IR/Constants.h
index c05133a3dac..11ca8008f29 100644
--- a/llvm/include/llvm/IR/Constants.h
+++ b/llvm/include/llvm/IR/Constants.h
@@ -1175,7 +1175,8 @@ public:
/// gets constant-folded, the type changes, or the expression is otherwise
/// canonicalized. This parameter should almost always be \c false.
Constant *getWithOperands(ArrayRef<Constant *> Ops, Type *Ty,
- bool OnlyIfReduced = false) const;
+ bool OnlyIfReduced = false,
+ Type *SrcTy = nullptr) const;
/// getAsInstruction - Returns an Instruction which implements the same
/// operation as this ConstantExpr. The instruction is not linked to any basic
diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp
index 9365653516e..798ea2470fa 100644
--- a/llvm/lib/IR/Constants.cpp
+++ b/llvm/lib/IR/Constants.cpp
@@ -1245,7 +1245,7 @@ ConstantExpr::getWithOperandReplaced(unsigned OpNo, Constant *Op) const {
/// operands replaced with the specified values. The specified array must
/// have the same number of operands as our current one.
Constant *ConstantExpr::getWithOperands(ArrayRef<Constant *> Ops, Type *Ty,
- bool OnlyIfReduced) const {
+ bool OnlyIfReduced, Type *SrcTy) const {
assert(Ops.size() == getNumOperands() && "Operand count mismatch!");
// If no operands changed return self.
@@ -1283,10 +1283,13 @@ Constant *ConstantExpr::getWithOperands(ArrayRef<Constant *> Ops, Type *Ty,
case Instruction::ShuffleVector:
return ConstantExpr::getShuffleVector(Ops[0], Ops[1], Ops[2],
OnlyIfReducedTy);
- case Instruction::GetElementPtr:
- return ConstantExpr::getGetElementPtr(nullptr, Ops[0], Ops.slice(1),
- cast<GEPOperator>(this)->isInBounds(),
- OnlyIfReducedTy);
+ case Instruction::GetElementPtr: {
+ auto *GEPO = cast<GEPOperator>(this);
+ assert(SrcTy || (Ops[0]->getType() == getOperand(0)->getType()));
+ return ConstantExpr::getGetElementPtr(
+ SrcTy ? SrcTy : GEPO->getSourceElementType(), Ops[0], Ops.slice(1),
+ GEPO->isInBounds(), OnlyIfReducedTy);
+ }
case Instruction::ICmp:
case Instruction::FCmp:
return ConstantExpr::getCompare(getPredicate(), Ops[0], Ops[1],
diff --git a/llvm/lib/Transforms/Utils/ValueMapper.cpp b/llvm/lib/Transforms/Utils/ValueMapper.cpp
index c9e474da8af..414d4eaa68d 100644
--- a/llvm/lib/Transforms/Utils/ValueMapper.cpp
+++ b/llvm/lib/Transforms/Utils/ValueMapper.cpp
@@ -19,6 +19,7 @@
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Metadata.h"
+#include "llvm/IR/Operator.h"
using namespace llvm;
// Out of line method to get vtable etc for class.
@@ -127,9 +128,13 @@ Value *llvm::MapValue(const Value *V, ValueToValueMapTy &VM, RemapFlags Flags,
Ops.push_back(MapValue(cast<Constant>(C->getOperand(OpNo)), VM,
Flags, TypeMapper, Materializer));
}
-
+ Type *NewSrcTy = nullptr;
+ if (TypeMapper)
+ if (auto *GEPO = dyn_cast<GEPOperator>(C))
+ NewSrcTy = TypeMapper->remapType(GEPO->getSourceElementType());
+
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C))
- return VM[V] = CE->getWithOperands(Ops, NewTy);
+ return VM[V] = CE->getWithOperands(Ops, NewTy, false, NewSrcTy);
if (isa<ConstantArray>(C))
return VM[V] = ConstantArray::get(cast<ArrayType>(NewTy), Ops);
if (isa<ConstantStruct>(C))
OpenPOWER on IntegriCloud