llvm-6502/test/Transforms/DeadStoreElimination/cs-cs-aliasing.ll
Hal Finkel 8f609696e0 Improve BasicAA CS-CS queries (redux)
This reverts, "r213024 - Revert r212572 "improve BasicAA CS-CS queries", it
causes PR20303." with a fix for the bug in pr20303. As it turned out, the
relevant code was both wrong and over-conservative (because, as with the code
it replaced, it would return the overall ModRef mask even if just Ref had been
implied by the argument aliasing results). Hopefully, this correctly fixes both
problems.

Thanks to Nick Lewycky for reducing the test case for pr20303 (which I've
cleaned up a little and added in DSE's test directory). The BasicAA test has
also been updated to check for this error.

Original commit message:

BasicAA contains knowledge of certain intrinsics, such as memcpy and memset,
and uses that information to form more-accurate answers to CallSite vs. Loc
ModRef queries. Unfortunately, it did not use this information when answering
CallSite vs. CallSite queries.

Generically, when an intrinsic takes one or more pointers and the intrinsic is
marked only to read/write from its arguments, the offset/size is unknown. As a
result, the generic code that answers CallSite vs. CallSite (and CallSite vs.
Loc) queries in AA uses UnknownSize when forming Locs from an intrinsic's
arguments. While BasicAA's CallSite vs. Loc override could use more-accurate
size information for some intrinsics, it did not do the same for CallSite vs.
CallSite queries.

This change refactors the intrinsic-specific logic in BasicAA into a generic AA
query function: getArgLocation, which is overridden by BasicAA to supply the
intrinsic-specific knowledge, and used by AA's generic implementation. This
allows the intrinsic-specific knowledge to be used by both CallSite vs. Loc and
CallSite vs. CallSite queries, and simplifies the BasicAA implementation.

Currently, only one function, Mac's memset_pattern16, is handled by BasicAA
(all the rest are intrinsics). As a side-effect of this refactoring, BasicAA's
getModRefBehavior override now also returns OnlyAccessesArgumentPointees for
this function (which is an improvement).

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@213219 91177308-0d34-0410-b5e6-96231b3b80d8
2014-07-17 01:28:25 +00:00

75 lines
3.5 KiB
LLVM

; RUN: opt -basicaa -dse -S < %s | FileCheck %s
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
%class.basic_string = type { %"class.__gnu_cxx::__versa_string" }
%"class.__gnu_cxx::__versa_string" = type { %"class.__gnu_cxx::__sso_string_base" }
%"class.__gnu_cxx::__sso_string_base" = type { %"struct.__gnu_cxx::__vstring_utility<char, std::char_traits<char>, std::allocator<char> >::_Alloc_hider", i64, %union.anon }
%"struct.__gnu_cxx::__vstring_utility<char, std::char_traits<char>, std::allocator<char> >::_Alloc_hider" = type { i8* }
%union.anon = type { i64, [8 x i8] }
; Function Attrs: nounwind
declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) #0
; Function Attrs: noinline nounwind readonly uwtable
declare zeroext i1 @callee_takes_string(%class.basic_string* nonnull) #1 align 2
; Function Attrs: nounwind uwtable
define weak_odr zeroext i1 @test() #2 align 2 {
; CHECK-LABEL: @test
bb:
%tmp = alloca %class.basic_string, align 8
%tmp1 = alloca %class.basic_string, align 8
%tmp3 = getelementptr inbounds %class.basic_string* %tmp, i64 0, i32 0, i32 0, i32 2
%tmp4 = bitcast %union.anon* %tmp3 to i8*
%tmp5 = getelementptr inbounds %class.basic_string* %tmp, i64 0, i32 0, i32 0, i32 0, i32 0
%tmp6 = getelementptr inbounds %class.basic_string* %tmp, i64 0, i32 0, i32 0, i32 1
%tmp7 = getelementptr inbounds i8* %tmp4, i64 1
%tmp8 = bitcast %class.basic_string* %tmp to i8*
%tmp9 = bitcast i64 0 to i64
%tmp10 = getelementptr inbounds %class.basic_string* %tmp1, i64 0, i32 0, i32 0, i32 2
%tmp11 = bitcast %union.anon* %tmp10 to i8*
%tmp12 = getelementptr inbounds %class.basic_string* %tmp1, i64 0, i32 0, i32 0, i32 0, i32 0
%tmp13 = getelementptr inbounds %class.basic_string* %tmp1, i64 0, i32 0, i32 0, i32 1
%tmp14 = getelementptr inbounds i8* %tmp11, i64 1
%tmp15 = bitcast %class.basic_string* %tmp1 to i8*
br label %_ZN12basic_stringIcSt11char_traitsIcESaIcEEC2EPKcRKS2_.exit
_ZN12basic_stringIcSt11char_traitsIcESaIcEEC2EPKcRKS2_.exit: ; preds = %bb
store i8* %tmp4, i8** %tmp5, align 8
store i8 62, i8* %tmp4, align 8
store i64 1, i64* %tmp6, align 8
store i8 0, i8* %tmp7, align 1
%tmp16 = call zeroext i1 @callee_takes_string(%class.basic_string* nonnull %tmp)
br label %_ZN9__gnu_cxx17__sso_string_baseIcSt11char_traitsIcESaIcEED2Ev.exit3
_ZN9__gnu_cxx17__sso_string_baseIcSt11char_traitsIcESaIcEED2Ev.exit3: ; preds = %_ZN12basic_stringIcSt11char_traitsIcESaIcEEC2EPKcRKS2_.exit
; CHECK: _ZN9__gnu_cxx17__sso_string_baseIcSt11char_traitsIcESaIcEED2Ev.exit3:
; The following can be read through the call %tmp17:
store i8* %tmp11, i8** %tmp12, align 8
store i8 125, i8* %tmp11, align 8
store i64 1, i64* %tmp13, align 8
store i8 0, i8* %tmp14, align 1
; CHECK: store i8* %tmp11, i8** %tmp12, align 8
; CHECK: store i8 125, i8* %tmp11, align 8
; CHECK: store i64 1, i64* %tmp13, align 8
; CHECK: store i8 0, i8* %tmp14, align 1
%tmp17 = call zeroext i1 @callee_takes_string(%class.basic_string* nonnull %tmp1)
call void @llvm.memset.p0i8.i64(i8* %tmp11, i8 -51, i64 16, i32 8, i1 false) #0
call void @llvm.memset.p0i8.i64(i8* %tmp15, i8 -51, i64 32, i32 8, i1 false) #0
call void @llvm.memset.p0i8.i64(i8* %tmp4, i8 -51, i64 16, i32 8, i1 false) #0
call void @llvm.memset.p0i8.i64(i8* %tmp8, i8 -51, i64 32, i32 8, i1 false) #0
ret i1 %tmp17
}
attributes #0 = { nounwind }
attributes #1 = { noinline nounwind readonly uwtable }
attributes #2 = { nounwind uwtable }