[llvm-dev] GEP index canonicalization
Manuel Jacob via llvm-dev
llvm-dev at lists.llvm.org
Wed May 25 06:18:49 PDT 2016
*ping*
On 2016-05-19 02:56, Manuel Jacob via llvm-dev wrote:
> Hi,
>
> InstCombine canonicalizes index operands (unless they are into struct
> types) to pointer size. The comment says: "If we are using a wider
> index than needed for this platform, shrink it to what we need. If
> narrower, sign-extend it to what we need. This explicit cast can make
> subsequent optimizations more obvious.".
>
> For our architecture, the canonicalization is a bit problematic. For
> example, our load operation can take any width and will implicitly
> sign-extend or truncate it. The extra explicit cast however will show
> up as an extra operation in the machine code. It is of course easy to
> eliminate the cast in a peephole optimization in the backend.
>
> More interesting is the effect of this canonicalization on subsequent
> transformations. Which optimizations are more obvious now, as the
> comment says? I found examples where it enables IndVarSimplify to
> promote an index variable to pointer size. However that introduces
> truncations, which can't be optimized away by simple peephole
> optimizations in the backend anymore.
>
> Does it make sense to add a target hook for this?
>
> -Manuel
>
>
> Example:
>
> define void @foo(i32 %n, i32* %a) {
> entry:
> %cmp1 = icmp slt i32 0, %n
> br i1 %cmp1, label %for.body, label %for.end
>
> for.body: ; preds = %for.body,
> %entry
> %i = phi i32 [ %inc, %for.body ], [ 0, %entry ]
> %ptr = getelementptr inbounds i32, i32* %a, i32 %i
> store i32 %i, i32* %ptr, align 4
> %inc = add nsw i32 %i, 1
> %cmp = icmp slt i32 %inc, %n
> br i1 %cmp, label %for.body, label %for.end
>
> for.end: ; preds = %for.body,
> %entry
> ret void
> }
>
>
> InstCombine introduces a sext instruction:
>
> define void @foo(i32 %n, i32* %a) {
> entry:
> %cmp1 = icmp sgt i32 %n, 0
> br i1 %cmp1, label %for.body, label %for.end
>
> for.body: ; preds = %for.body,
> %entry
> %i = phi i32 [ %inc, %for.body ], [ 0, %entry ]
> %0 = sext i32 %i to i64
> %ptr = getelementptr inbounds i32, i32* %a, i64 %0
> store i32 %i, i32* %ptr, align 4
> %inc = add nsw i32 %i, 1
> %cmp = icmp slt i32 %inc, %n
> br i1 %cmp, label %for.body, label %for.end
>
> for.end: ; preds = %for.body,
> %entry
> ret void
> }
>
>
> IndVarSimplify promotes %i to i64, requiring two additional truncs:
>
> define void @foo(i32 %n, i32* %a) {
> entry:
> %cmp1 = icmp sgt i32 %n, 0
> br i1 %cmp1, label %for.body.preheader, label %for.end
>
> for.body.preheader: ; preds = %entry
> br label %for.body
>
> for.body: ; preds =
> %for.body.preheader, %for.body
> %indvars.iv = phi i64 [ 0, %for.body.preheader ], [
> %indvars.iv.next, %for.body ]
> %ptr = getelementptr inbounds i32, i32* %a, i64 %indvars.iv
> %0 = trunc i64 %indvars.iv to i32
> store i32 %0, i32* %ptr, align 4
> %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
> %lftr.wideiv = trunc i64 %indvars.iv.next to i32
> %exitcond = icmp ne i32 %lftr.wideiv, %n
> br i1 %exitcond, label %for.body, label %for.end.loopexit
>
> for.end.loopexit: ; preds = %for.body
> br label %for.end
>
> for.end: ; preds =
> %for.end.loopexit, %entry
> ret void
> }
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
More information about the llvm-dev
mailing list