llvm-project/llvm/test/Analysis/BasicAA/gep-implicit-trunc-32-bit-p...

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

100 lines
3.2 KiB
LLVM
Raw Normal View History

2022-03-09 06:00:08 +08:00
; RUN: opt -aa-pipeline=basic-aa -passes=aa-eval -print-all-alias-modref-info -disable-output %s 2>&1 | FileCheck %s
target datalayout = "p:32:32:32"
; Test cases with i64 bit GEP indices that will get truncated implicitly to 32
; bit due to the datalayout.
declare void @llvm.assume(i1)
define void @mustalias_overflow_in_32_bit_constants(i8* %ptr) {
; CHECK-LABEL: Function: mustalias_overflow_in_32_bit_constants: 3 pointers, 0 call sites
; CHECK-NEXT: MustAlias: i8* %gep.1, i8* %ptr
; CHECK-NEXT: MustAlias: i8* %gep.2, i8* %ptr
; CHECK-NEXT: MustAlias: i8* %gep.1, i8* %gep.2
;
load i8, i8* %ptr
%gep.1 = getelementptr i8, i8* %ptr, i64 4294967296
store i8 0, i8* %gep.1
%gep.2 = getelementptr i8, i8* %ptr, i64 0
store i8 1, i8* %gep.2
ret void
}
define void @mustalias_overflow_in_32_with_var_index([1 x i8]* %ptr, i64 %n) {
; CHECK-LABEL: Function: mustalias_overflow_in_32_with_var_index
[BasicAA] Don't unnecessarily extend pointer size BasicAA GEP decomposition currently performs all calculation on the maximum pointer size, but at least 64-bit, with an option to double the size. The code comment claims that this improves analysis power when working with uint64_t indices on 32-bit systems. However, I don't see how this can be, at least while maintaining correctness: When working on canonical code, the GEP indices will have GEP index size. If the original code worked on uint64_t with a 32-bit size_t, then there will be truncs inserted before use as a GEP index. Linear expression decomposition does not look through truncs, so this will be an opaque value as far as GEP decomposition is concerned. Working on a wider pointer size does not help here (or have any effect at all). When working on non-canonical code (before first InstCombine), the GEP indices are implicitly truncated to GEP index size. The BasicAA code currently just ignores this fact completely, and pretends that this truncation doesn't happen. This is incorrect and will be addressed by D110977. I believe that for correctness reasons, it is important to work on the actual GEP index size to properly model potential overflow. BasicAA tries to patch over the fact that it uses the wrong size (see adjustToPointerSize), but it only does that in limited cases (only for constant values, and not all of them either). I'd like to move this code towards always working on the correct size, and dropping these artificial pointer size adjustments is the first step towards that. Differential Revision: https://reviews.llvm.org/D110657
2021-09-29 04:21:37 +08:00
; CHECK: MustAlias: i8* %gep.1, i8* %gep.2
;
load [1 x i8], [1 x i8]* %ptr
%gep.1 = getelementptr [1 x i8], [1 x i8]* %ptr, i64 %n, i64 4294967296
store i8 0, i8* %gep.1
%gep.2 = getelementptr [1 x i8], [1 x i8]* %ptr, i64 %n, i64 0
store i8 1, i8* %gep.2
ret void
}
define void @noalias_overflow_in_32_bit_constants(i8* %ptr) {
; CHECK-LABEL: Function: noalias_overflow_in_32_bit_constants: 3 pointers, 0 call sites
; CHECK-NEXT: MustAlias: i8* %gep.1, i8* %ptr
; CHECK-NEXT: NoAlias: i8* %gep.2, i8* %ptr
; CHECK-NEXT: NoAlias: i8* %gep.1, i8* %gep.2
;
load i8, i8* %ptr
%gep.1 = getelementptr i8, i8* %ptr, i64 4294967296
store i8 0, i8* %gep.1
%gep.2 = getelementptr i8, i8* %ptr, i64 1
store i8 1, i8* %gep.2
ret void
}
; The GEP indices get implicitly truncated to 32 bit, so multiples of 2^32
; (=4294967296) will be 0.
; See https://alive2.llvm.org/ce/z/HHjQgb.
define void @mustalias_overflow_in_32_bit_add_mul_gep(i8* %ptr, i64 %i) {
; CHECK-LABEL: Function: mustalias_overflow_in_32_bit_add_mul_gep: 3 pointers, 1 call sites
; CHECK-NEXT: MayAlias: i8* %gep.1, i8* %ptr
; CHECK-NEXT: MayAlias: i8* %gep.2, i8* %ptr
; CHECK-NEXT: MayAlias: i8* %gep.1, i8* %gep.2
;
load i8, i8* %ptr
%s.1 = icmp sgt i64 %i, 0
call void @llvm.assume(i1 %s.1)
%mul = mul nuw nsw i64 %i, 4294967296
%add = add nuw nsw i64 %mul, %i
%gep.1 = getelementptr i8, i8* %ptr, i64 %add
store i8 0, i8* %gep.1
%gep.2 = getelementptr i8, i8* %ptr, i64 %i
store i8 1, i8* %gep.2
ret void
}
define void @mayalias_overflow_in_32_bit_non_zero(i8* %ptr, i64 %n) {
; CHECK-LABEL: Function: mayalias_overflow_in_32_bit_non_zero
; CHECK: MayAlias: i8* %gep, i8* %ptr
;
load i8, i8* %ptr
%c = icmp ne i64 %n, 0
call void @llvm.assume(i1 %c)
store i8 0, i8* %ptr
%gep = getelementptr i8, i8* %ptr, i64 %n
store i8 1, i8* %gep
ret void
}
define void @mayalias_overflow_in_32_bit_positive(i8* %ptr, i64 %n) {
; CHECK-LABEL: Function: mayalias_overflow_in_32_bit_positive
; CHECK: NoAlias: i8* %gep.1, i8* %ptr
; CHECK: MayAlias: i8* %gep.2, i8* %ptr
; CHECK: MayAlias: i8* %gep.1, i8* %gep.2
;
load i8, i8* %ptr
%c = icmp sgt i64 %n, 0
call void @llvm.assume(i1 %c)
%gep.1 = getelementptr i8, i8* %ptr, i64 -1
store i8 0, i8* %gep.1
%gep.2 = getelementptr i8, i8* %ptr, i64 %n
store i8 1, i8* %gep.2
ret void
}