diff options
author | Chris Lattner <sabre@nondot.org> | 2009-09-15 06:28:12 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2009-09-15 06:28:12 +0000 |
commit | dd4238e04dc8a5144d9c19bd53cf9650d1472309 (patch) | |
tree | 05cce3279e9f3e5beb16dff136236dcfd5b7e584 | |
parent | a51c39cc3265f5d0d5de87b4a3ef9332c83556e1 (diff) | |
download | external_llvm-dd4238e04dc8a5144d9c19bd53cf9650d1472309.zip external_llvm-dd4238e04dc8a5144d9c19bd53cf9650d1472309.tar.gz external_llvm-dd4238e04dc8a5144d9c19bd53cf9650d1472309.tar.bz2 |
fix PR4963: folding insertvalue would sometimes turn a packed struct into
an unpacked one.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@81845 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/VMCore/ConstantFold.cpp | 44 | ||||
-rw-r--r-- | test/Assembler/insertextractvalue.ll | 6 |
2 files changed, 30 insertions, 20 deletions
diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp index 9c9ac04..8641f77 100644 --- a/lib/VMCore/ConstantFold.cpp +++ b/lib/VMCore/ConstantFold.cpp @@ -499,17 +499,19 @@ Constant *llvm::ConstantFoldInsertValueInstruction(LLVMContext &Context, if (isa<UndefValue>(Agg)) { // Insertion of constant into aggregate undef - // Optimize away insertion of undef + // Optimize away insertion of undef. if (isa<UndefValue>(Val)) return const_cast<Constant*>(Agg); + // Otherwise break the aggregate undef into multiple undefs and do - // the insertion + // the insertion. const CompositeType *AggTy = cast<CompositeType>(Agg->getType()); unsigned numOps; if (const ArrayType *AR = dyn_cast<ArrayType>(AggTy)) numOps = AR->getNumElements(); else numOps = cast<StructType>(AggTy)->getNumElements(); + std::vector<Constant*> Ops(numOps); for (unsigned i = 0; i < numOps; ++i) { const Type *MemberTy = AggTy->getTypeAtIndex(i); @@ -520,24 +522,27 @@ Constant *llvm::ConstantFoldInsertValueInstruction(LLVMContext &Context, UndefValue::get(MemberTy); Ops[i] = const_cast<Constant*>(Op); } - if (isa<StructType>(AggTy)) - return ConstantStruct::get(Context, Ops); - else - return ConstantArray::get(cast<ArrayType>(AggTy), Ops); + + if (const StructType* ST = dyn_cast<StructType>(AggTy)) + return ConstantStruct::get(Context, Ops, ST->isPacked()); + return ConstantArray::get(cast<ArrayType>(AggTy), Ops); } + if (isa<ConstantAggregateZero>(Agg)) { // Insertion of constant into aggregate zero - // Optimize away insertion of zero + // Optimize away insertion of zero. if (Val->isNullValue()) return const_cast<Constant*>(Agg); + // Otherwise break the aggregate zero into multiple zeros and do - // the insertion + // the insertion. const CompositeType *AggTy = cast<CompositeType>(Agg->getType()); unsigned numOps; if (const ArrayType *AR = dyn_cast<ArrayType>(AggTy)) numOps = AR->getNumElements(); else numOps = cast<StructType>(AggTy)->getNumElements(); + std::vector<Constant*> Ops(numOps); for (unsigned i = 0; i < numOps; ++i) { const Type *MemberTy = AggTy->getTypeAtIndex(i); @@ -549,13 +554,14 @@ Constant *llvm::ConstantFoldInsertValueInstruction(LLVMContext &Context, Constant::getNullValue(MemberTy); Ops[i] = const_cast<Constant*>(Op); } - if (isa<StructType>(AggTy)) - return ConstantStruct::get(Context, Ops); - else - return ConstantArray::get(cast<ArrayType>(AggTy), Ops); + + if (const StructType* ST = dyn_cast<StructType>(AggTy)) + return ConstantStruct::get(Context, Ops, ST->isPacked()); + return ConstantArray::get(cast<ArrayType>(AggTy), Ops); } + if (isa<ConstantStruct>(Agg) || isa<ConstantArray>(Agg)) { - // Insertion of constant into aggregate constant + // Insertion of constant into aggregate constant. std::vector<Constant*> Ops(Agg->getNumOperands()); for (unsigned i = 0; i < Agg->getNumOperands(); ++i) { const Constant *Op = @@ -565,12 +571,10 @@ Constant *llvm::ConstantFoldInsertValueInstruction(LLVMContext &Context, Agg->getOperand(i); Ops[i] = const_cast<Constant*>(Op); } - Constant *C; - if (isa<StructType>(Agg->getType())) - C = ConstantStruct::get(Context, Ops); - else - C = ConstantArray::get(cast<ArrayType>(Agg->getType()), Ops); - return C; + + if (const StructType* ST = dyn_cast<StructType>(Agg->getType())) + return ConstantStruct::get(Context, Ops, ST->isPacked()); + return ConstantArray::get(cast<ArrayType>(Agg->getType()), Ops); } return 0; @@ -585,7 +589,7 @@ Constant *llvm::ConstantFoldBinaryInstruction(LLVMContext &Context, if (C1->getType() == Type::getPPC_FP128Ty(Context)) return 0; - // Handle UndefValue up front + // Handle UndefValue up front. if (isa<UndefValue>(C1) || isa<UndefValue>(C2)) { switch (Opcode) { case Instruction::Xor: diff --git a/test/Assembler/insertextractvalue.ll b/test/Assembler/insertextractvalue.ll index 3581238..2f5521f 100644 --- a/test/Assembler/insertextractvalue.ll +++ b/test/Assembler/insertextractvalue.ll @@ -21,3 +21,9 @@ define float @dar({{i32},{float, double}}* %p) nounwind { store {{i32},{float, double}} insertvalue ({{i32},{float, double}} zeroinitializer, double 20.0, 1, 1), {{i32},{float, double}}* %p ret float extractvalue ({{i32},{float, double}} zeroinitializer, 1, 0) } + + +; PR4963 +define <{ i32, i32 }> @test57() { + ret <{ i32, i32 }> insertvalue (<{ i32, i32 }> zeroinitializer, i32 4, 1) +} |