[llvm-dev] InstCombine GEP

Nema, Ashutosh via llvm-dev llvm-dev at lists.llvm.org
Thu Aug 10 00:22:11 PDT 2017


Hi,

I have a doubt with GEP transformation in the instruction-combiner.

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.
I expected the GEPs to use the actual type offsetting for which the memory is allocated.

Expected 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
}

In the above IR the GEP offsetting looks very explicit for the type struct.ABC.

Looking at the InstCombiner source found the below code is responsible for it:
1914   /// See if we can simplify:
1915   ///   X = bitcast A* to B*
1916   ///   Y = gep X, <...constant indices...>
1917   /// into a gep of the original struct.  This is important for SROA and alias
1918   /// analysis of unions.  If "A" is also a bitcast, wait for A/X to be merged.
1919   if (BitCastInst *BCI = dyn_cast<BitCastInst>(PtrOp)) {
1920    ....

I'm not sure how transforming GEP offset to i8 type will help alias analysis & SROA for the mentioned test case.

Regards,
Ashutosh

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170810/f17a3f0e/attachment.html>


More information about the llvm-dev mailing list