[PATCH] D99249: [PassManager] Run additional LICM before LoopRotate
Nikita Popov via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Thu Apr 1 14:20:01 PDT 2021
nikic added a comment.
Here's a reduced version of @lebedev.ri's example:
define void @test(i32* dereferenceable(4) %ptr, i32 %size) {
entry:
br label %for.cond
for.cond:
%iv = phi i32 [ 0, %entry ], [ %iv.next, %for.cont ]
%cmp = icmp ult i32 %iv, %size
br i1 %cmp, label %for.cont, label %for.end
for.cont:
%val = load i32, i32* %ptr, align 4
%iv.next = add nsw i32 %iv, 1
call void @use(i32 %val) inaccessiblememonly
br label %for.cond
for.end:
ret void
}
declare void @use(i32)
The problem is that the load is not speculatable due to lack of align attribute. After `-loop-rotate` we have
define void @test(i32* align 4 dereferenceable(4) %ptr, i32 %size) {
entry:
%cmp1 = icmp ult i32 0, %size
br i1 %cmp1, label %for.cont.lr.ph, label %for.end
for.cont.lr.ph: ; preds = %entry
br label %for.cont
for.cont: ; preds = %for.cont.lr.ph, %for.cont
%iv2 = phi i32 [ 0, %for.cont.lr.ph ], [ %iv.next, %for.cont ]
%val = load i32, i32* %ptr, align 4
%iv.next = add nsw i32 %iv2, 1
call void @use(i32 %val) #0
%cmp = icmp ult i32 %iv.next, %size
br i1 %cmp, label %for.cont, label %for.cond.for.end_crit_edge
for.cond.for.end_crit_edge: ; preds = %for.cont
br label %for.end
for.end: ; preds = %for.cond.for.end_crit_edge, %entry
ret void
}
in which case the `load` is executed unconditionally (if the loop is executed) and can be hoisted. Thus the need for `-licm` after `-loop-rotate`.
Based on @thopre's comments, it seems like lack of align attribute on C++ `this` pointers was also the problem for his case. It's possible that I'm missing some C++ subtlety here, but I believe the lack of align attribute here is just an oversight. At some point, we changed LLVM to no longer assume that pointers without alignment information have natural alignment, and clang was adjusted in D80166 <https://reviews.llvm.org/D80166> to emit align attributes for dereferenceable pointers to compensate for that change. However, the align attributes were added only for reference types, not for `this` pointers. Notably https://github.com/llvm/llvm-project/blob/17800f900dca8243773dec5f90578cce03069b8f/clang/lib/CodeGen/CGCall.cpp#L2310 is missing the align attribute. We're probably missing optimizations not just in LICM because of that.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D99249/new/
https://reviews.llvm.org/D99249
More information about the llvm-commits
mailing list