Skip to content

Commit

Permalink
Update InstCombine to transform aggregate stores into scalar stores.
Browse files Browse the repository at this point in the history
Summary: This is a first step toward getting proper support for aggregate loads and stores.

Test Plan: Added unittests

Reviewers: reames, chandlerc

Reviewed By: chandlerc

Subscribers: majnemer, joker.eph, chandlerc, llvm-commits

Differential Revision: http://reviews.llvm.org/D7780

Patch by Amaury Sechet

From: Mehdi Amini <mehdi.amini@apple.com>
llvm-svn: 232284
  • Loading branch information
joker-eph committed Mar 14, 2015
1 parent 4a121fa commit b344ac9
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 0 deletions.
28 changes: 28 additions & 0 deletions llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -818,6 +818,30 @@ static bool combineStoreToValueType(InstCombiner &IC, StoreInst &SI) {
return false;
}

static bool unpackStoreToAggregate(InstCombiner &IC, StoreInst &SI) {
// FIXME: We could probably with some care handle both volatile and atomic
// stores here but it isn't clear that this is important.
if (!SI.isSimple())
return false;

Value *V = SI.getValueOperand();
Type *T = V->getType();

if (!T->isAggregateType())
return false;

if (StructType *ST = dyn_cast<StructType>(T)) {
// If the struct only have one element, we unpack.
if (ST->getNumElements() == 1) {
V = IC.Builder->CreateExtractValue(V, 0);
combineStoreToNewValue(IC, SI, V);
return true;
}
}

return false;
}

/// equivalentAddressValues - Test if A and B will obviously have the same
/// value. This includes recognizing that %t0 and %t1 will have the same
/// value in code like this:
Expand Down Expand Up @@ -867,6 +891,10 @@ Instruction *InstCombiner::visitStoreInst(StoreInst &SI) {
else if (StoreAlign == 0)
SI.setAlignment(EffectiveStoreAlign);

// Try to canonicalize the stored type.
if (unpackStoreToAggregate(*this, SI))
return EraseInstFromFunction(SI);

// Replace GEP indices if possible.
if (Instruction *NewGEPI = replaceGEPIdxWithZero(*this, Ptr, SI)) {
Worklist.Add(NewGEPI);
Expand Down
31 changes: 31 additions & 0 deletions llvm/test/Transforms/InstCombine/unpack-fca.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
; RUN: opt -instcombine -S < %s | FileCheck %s

target datalayout = "e-i64:64-f80:128-n8:16:32:64"
target triple = "x86_64-unknown-linux-gnu"

%A__vtbl = type { i8*, i32 (%A*)* }
%A = type { %A__vtbl* }

@A__vtblZ = constant %A__vtbl { i8* null, i32 (%A*)* @A.foo }

declare i32 @A.foo(%A* nocapture %this)

declare i8* @allocmemory(i64)

define void @structA() {
body:
%0 = tail call i8* @allocmemory(i64 32)
%1 = bitcast i8* %0 to %A*
; CHECK: store %A__vtbl* @A__vtblZ
store %A { %A__vtbl* @A__vtblZ }, %A* %1, align 8
ret void
}

define void @structOfA() {
body:
%0 = tail call i8* @allocmemory(i64 32)
%1 = bitcast i8* %0 to { %A }*
; CHECK: store %A__vtbl* @A__vtblZ
store { %A } { %A { %A__vtbl* @A__vtblZ } }, { %A }* %1, align 8
ret void
}

0 comments on commit b344ac9

Please sign in to comment.