Page MenuHomePhabricator

Inst Combine GEP Flatten
Needs ReviewPublic

Authored by ashutosh.nema on Aug 18 2017, 9:23 AM.

Details

Summary

InstCombiner transform GEP accesses to source type, ideally it should keep the GEP to the actual/destination type.

Consider below test-case:
struct ABC {

int A;
int B[100];
struct XYZ {
  int X;
  int Y[100];
} OBJ;

};
void Setup(struct ABC *);
int foo(int offset) {

struct ABC *Ptr = malloc(sizeof(struct ABC));
Setup(Ptr);
return Ptr->OBJ.X + Ptr->OBJ.Y[33];

}

Generated IR for the test-case:
define i32 @foo(i32 %offset) local_unnamed_addr #0 {
entry:

%call = tail call i8* @malloc(i64 808)
%0 = bitcast i8* %call to %struct.ABC*
tail call void @Setup(%struct.ABC* %0) #3
%OBJ = getelementptr inbounds i8, i8* %call, i64 404
%X = bitcast i8* %OBJ to i32*
%1 = load i32, i32* %X, align 4, !tbaa !2
%arrayidx = getelementptr inbounds i8, i8* %call, i64 540
%2 = bitcast i8* %arrayidx to i32*
%3 = load i32, i32* %2, align 4, !tbaa !8
%add = add nsw i32 %3, %1
ret i32 %add

}

Instruction combiner transforms GEPs to i8 type, because of this the GEP offset looks weird and the actual type information is missing on GEP.

This change is to retain the GEP’s to the actual type.
For the above test it will now generate below IR:
; Function Attrs: nounwind uwtable
define i32 @foo(i32 %offset) local_unnamed_addr #0 {
entry:

%call = tail call i8* @malloc(i64 808)
%0 = bitcast i8* %call to %struct.ABC*
tail call void @Setup(%struct.ABC* %0) #3
%X = getelementptr inbounds %struct.ABC, %struct.ABC* %0, i64 0, i32 2, i32 0
%1 = load i32, i32* %X, align 4, !tbaa !2
%arrayidx = getelementptr inbounds %struct.ABC, %struct.ABC* %0, i64 0, i32 2, i32 1, i64 33
%2 = load i32, i32* %arrayidx, align 4, !tbaa !8
%add = add nsw i32 %2, %1
ret i32 %add

}

Diff Detail

Repository
rL LLVM

Event Timeline

ashutosh.nema created this revision.Aug 18 2017, 9:23 AM
ashutosh.nema added a subscriber: llvm-commits.
dberlin edited edge metadata.Aug 21 2017, 7:07 PM

I don't think there is any ideal here. In the example you give, it reduces the number of bitcasts. In some of the tests you've changed, it adds more.

Sorry for the late reply, I was on vacation.

In my understanding if we wants to retain destination type in some cases this change will generate extra bitcast.
As the source type & destination may be different.