[PATCH] D18738: Add new !unconditionally_dereferenceable load instruction metadata
whitequark via llvm-commits
llvm-commits at lists.llvm.org
Sun Apr 3 12:55:02 PDT 2016
whitequark added a comment.
I acknowledge that your analysis is correct, and I see your point about the transformations (assuming for sake of translation of your argument so that it translates to LICM that by `if(false)` you mean "a loop with zero trip count"). The core of the issue as I see it is that, when applied to self-contradictory IR, otherwise valid optimizations can bring undefined behavior "out of thin air".
However, this is something that already happens in LLVM. Consider this testcase:
target datalayout = "E-m:e-p:32:32-i8:8:8-i16:16:16-i64:32:32-f64:32:32-v64:32:32-v128:32:32-a0:0:32-n32"
%a = type { %b* }
%b = type { i32 }
define void @test() {
entry:
%arg = alloca %a
%ptr.f = getelementptr inbounds %a, %a* %arg, i32 0, i32 0
%val.f = load %b*, %b** %ptr.f, !invariant.load !0, !dereferenceable !1
br label %for.head
for.head:
%IND = phi i32 [ 0, %entry ], [ %IND.new, %for.body ]
%CMP = icmp slt i32 %IND, 0
br i1 %CMP, label %for.body, label %exit
for.body:
%ptr.x = getelementptr inbounds %b, %b* %val.f, i32 0, i32 0
%val.x = load i32, i32* %ptr.x, !invariant.load !0
call void @consume(i32 %val.x)
%IND.new = add i32 %IND, 1
br label %for.head
exit:
ret void
}
declare void @consume(i32)
!0 = !{}
!1 = !{ i64 4 }
The loop trip count is zero, and the second load is clearly undefined, but ToT LICM nevertheless hoists it.
Personally, I think that:
1. It is the responsibility of the frontend to not construct self-contradictory IR. There are far too many ways to do it that are not obviously wrong (and thus not easily rejected by the verifier), e.g. it is easy to do so with TBAA.
2. It is the responsibility of the middle-end to not construct self-contradictory IR when given non-self-contradictory IR. I.e. in your example the transformation introducing the code inside `if (false) { ... }` is clearly at fault, because there are some (dynamically dead) CFG paths that violate the invariants of the `!unconditionally_dereferenceable` marker and there were none before it.
Repository:
rL LLVM
http://reviews.llvm.org/D18738
More information about the llvm-commits
mailing list