This is most likely wrong.
But it eliminates 33% of instrumentation on webrtc/modules_unittests (number of memory accesses goes down from 290152 to 193998) and reduces binary size by 15% (from 74M to 64M) _and_ all existing asan tests pass.
This means that either our tests are bad or we are missing a good optimization opportunity.
Currently we instrument even the following code, which looks wrong:
define void @foo() uwtable sanitize_address {
entry:
%a = alloca i32, align 4 store i32 42, i32* %a, align 4 ret void
}
I've found one case which fails with this change. We do not instrument the store in this case:
define void @bar() sanitize_address {
entry:
%a = alloca [10 x i32], align 4 %e = getelementptr inbounds [10 x i32]* %a, i32 0, i64 12 store i32 42, i32* %e, align 4 ret void
; CHECK-LABEL: define void @bar
; CHECK: __asan_report
; CHECK: ret void
}
However, compiler should be able to recognize such cases (and it does because it issues a warning).
I am a bit lost.
There is Value::isGEPWithNoNotionalOverIndexing which looks like what we need (should eliminate array accesses with constant inbounds indices and struct field accesses). However, it does not give the desired effect.
Value::stripInBoundsConstantOffsets also looks like what we need and it gives the desired effect. However, there is a note that "Value::isGEPWithNoNotionalOverIndexing is not equivalant to, a subset of, or a superset of the "inbounds" property". Which suggests that stripInBoundsConstantOffsets is not what we want.
Also, is it possible to refer to an AllocaInst outside of its lifetime? It is not possible in C/C++ due to scoping rules, you simply can't mention a name that is out of scope. However, I am not sure about llvm and its transformations.
I am looking for advice here.
These seem out of place - should be moved after ADT.