continue;
}
+ // Replace %res = load { i32, i32 }* %alloc
+ // by
+ // %load.0 = load i32* %alloc.0
+ // %insert.0 insertvalue { i32, i32 } zeroinitializer, i32 %load.0, 0
+ // %load.1 = load i32* %alloc.1
+ // %insert = insertvalue { i32, i32 } %insert.0, i32 %load.1, 1
+ // (Also works for arrays instead of structs)
+ if (LoadInst *LI = dyn_cast<LoadInst>(User)) {
+ Value *Insert = UndefValue::get(LI->getType());
+ for (unsigned i = 0, e = ElementAllocas.size(); i != e; ++i) {
+ Value *Load = new LoadInst(ElementAllocas[i], "load", LI);
+ Insert = InsertValueInst::Create(Insert, Load, i, "insert", LI);
+ }
+ LI->replaceAllUsesWith(Insert);
+ LI->eraseFromParent();
+ continue;
+ }
+
+ // Replace store { i32, i32 } %val, { i32, i32 }* %alloc
+ // by
+ // %val.0 = extractvalue { i32, i32 } %val, 0
+ // store i32 %val.0, i32* %alloc.0
+ // %val.1 = extractvalue { i32, i32 } %val, 1
+ // store i32 %val.1, i32* %alloc.1
+ // (Also works for arrays instead of structs)
+ if (StoreInst *SI = dyn_cast<StoreInst>(User)) {
+ Value *Val = SI->getOperand(0);
+ for (unsigned i = 0, e = ElementAllocas.size(); i != e; ++i) {
+ Value *Extract = ExtractValueInst::Create(Val, i, Val->getName(), SI);
+ new StoreInst(Extract, ElementAllocas[i], SI);
+ }
+ SI->eraseFromParent();
+ continue;
+ }
+
GetElementPtrInst *GEPI = cast<GetElementPtrInst>(User);
// We now know that the GEP is of the form: GEP <ptr>, 0, <cst>
unsigned Idx =
if (BitCastInst *C = dyn_cast<BitCastInst>(User))
return isSafeUseOfBitCastedAllocation(C, AI, Info);
+ if (isa<LoadInst>(User))
+ return; // Loads (returning a first class aggregrate) are always rewritable
+
+ if (isa<StoreInst>(User) && User->getOperand(0) != AI)
+ return; // Store is ok if storing INTO the pointer, not storing the pointer
+
GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(User);
if (GEPI == 0)
return MarkUnsafe(Info);
Instruction *User = cast<Instruction>(*UI);
if (LoadInst *LI = dyn_cast<LoadInst>(User)) {
+ // FIXME: Loads of a first class aggregrate value could be converted to a
+ // series of loads and insertvalues
+ if (!LI->getType()->isSingleValueType())
+ return 0;
+
if (MergeInType(LI->getType(), UsedType, TD))
return 0;
} else if (StoreInst *SI = dyn_cast<StoreInst>(User)) {
// Storing the pointer, not into the value?
if (SI->getOperand(0) == V) return 0;
+
+ // FIXME: Stores of a first class aggregrate value could be converted to a
+ // series of extractvalues and stores
+ if (!SI->getOperand(0)->getType()->isSingleValueType())
+ return 0;
// NOTE: We could handle storing of FP imms into integers here!
--- /dev/null
+; This test shows an alloca of a struct and an array that can be reduced to
+; multiple variables easily. However, the alloca is used by a store
+; instruction, which was not possible before aggregrates were first class
+; values. This checks of scalarrepl splits up the struct and array properly.
+
+; RUN: llvm-as < %s | opt -scalarrepl | llvm-dis | not grep alloca
+
+define i32 @foo() {
+ %target = alloca { i32, i32 } ; <{ i32, i32 }*> [#uses=1]
+ ; Build a first class struct to store
+ %res1 = insertvalue { i32, i32 } undef, i32 1, 0 ; <{ i32, i32 }> [#uses=1]
+ %res2 = insertvalue { i32, i32 } %res1, i32 2, 1 ; <{ i32, i32 }> [#uses=1]
+ ; And store it
+ store { i32, i32 } %res2, { i32, i32 }* %target
+ ; Actually use %target, so it doesn't get removed alltogether
+ %ptr = getelementptr { i32, i32 }* %target, i32 0, i32 0
+ %val = load i32* %ptr
+ ret i32 %val
+}
+
+define i32 @bar() {
+ %target = alloca [ 2 x i32 ] ; <{ i32, i32 }*> [#uses=1]
+ ; Build a first class array to store
+ %res1 = insertvalue [ 2 x i32 ] undef, i32 1, 0 ; <{ i32, i32 }> [#uses=1]
+ %res2 = insertvalue [ 2 x i32 ] %res1, i32 2, 1 ; <{ i32, i32 }> [#uses=1]
+ ; And store it
+ store [ 2 x i32 ] %res2, [ 2 x i32 ]* %target
+ ; Actually use %target, so it doesn't get removed alltogether
+ %ptr = getelementptr [ 2 x i32 ]* %target, i32 0, i32 0
+ %val = load i32* %ptr
+ ret i32 %val
+}