[BasicAA] Support arbitrary pointer sizes (and fix an overflow bug)
Motivated by the discussion in D38499, this patch updates BasicAA to support
arbitrary pointer sizes by switching most remaining non-APInt calculations to
use APInt. The size of these APInts is set to the maximum pointer size (maximum
over all address spaces described by the data layout string).
Most of this translation is straightforward, but this patch contains a fix for
a bug that revealed itself during this translation process. In order for
test/Analysis/BasicAA/gep-and-alias.ll to pass, which is run with 32-bit
pointers, the intermediate calculations must be performed using 64-bit
integers. This is because, as noted in the patch, when GetLinearExpression
decomposes an expression into C1*V+C2, and we then multiply this by Scale, and
distribute, to get (C1*Scale)*V + C2*Scale, it can be the case that, even
through C1*V+C2 does not overflow for relevant values of V, (C2*Scale) can
overflow. If this happens, later logic will draw invalid conclusions from the
(base) offset value. Thus, when initially applying the APInt conversion,
because the maximum pointer size in this test is 32 bits, it started failing.
Suspicious, I created a 64-bit version of this test (included here), and that
failed (miscompiled) on trunk for a similar reason (the multiplication can
overflow).
After fixing this overflow bug, the first test case (at least) in
Analysis/BasicAA/q.bad.ll started failing. This is also a 32-bit test, and was
relying on having 64-bit intermediate values to have BasicAA return an accurate
result. In order to fix this problem, and because I believe that it is not
uncommon to use i64 indexing expressions in 32-bit code (especially portable
code using int64_t), it seems reasonable to always use at least 64-bit
integers. In this way, we won't regress our analysis capabilities (and there's
a command-line option added, so experimenting with this should be easy).
As pointed out by Eli during the review, there are other potential overflow
conditions that this patch does not address. Fixing those is left to follow-up
work.
Patch by me with contributions from Michael Ferguson (mferguson@cray.com).
Differential Revision: https://reviews.llvm.org/D38662
llvm-svn: 350220
2019-01-03 00:28:09 +08:00
|
|
|
; This testcase consists of alias relations on 128-bit pointers that
|
|
|
|
; should be completely resolvable by basicaa.
|
|
|
|
|
2020-06-27 05:58:01 +08:00
|
|
|
; RUN: opt < %s -basic-aa -aa-eval -print-no-aliases -print-may-aliases -print-must-aliases -disable-output 2>&1 | FileCheck %s
|
[BasicAA] Support arbitrary pointer sizes (and fix an overflow bug)
Motivated by the discussion in D38499, this patch updates BasicAA to support
arbitrary pointer sizes by switching most remaining non-APInt calculations to
use APInt. The size of these APInts is set to the maximum pointer size (maximum
over all address spaces described by the data layout string).
Most of this translation is straightforward, but this patch contains a fix for
a bug that revealed itself during this translation process. In order for
test/Analysis/BasicAA/gep-and-alias.ll to pass, which is run with 32-bit
pointers, the intermediate calculations must be performed using 64-bit
integers. This is because, as noted in the patch, when GetLinearExpression
decomposes an expression into C1*V+C2, and we then multiply this by Scale, and
distribute, to get (C1*Scale)*V + C2*Scale, it can be the case that, even
through C1*V+C2 does not overflow for relevant values of V, (C2*Scale) can
overflow. If this happens, later logic will draw invalid conclusions from the
(base) offset value. Thus, when initially applying the APInt conversion,
because the maximum pointer size in this test is 32 bits, it started failing.
Suspicious, I created a 64-bit version of this test (included here), and that
failed (miscompiled) on trunk for a similar reason (the multiplication can
overflow).
After fixing this overflow bug, the first test case (at least) in
Analysis/BasicAA/q.bad.ll started failing. This is also a 32-bit test, and was
relying on having 64-bit intermediate values to have BasicAA return an accurate
result. In order to fix this problem, and because I believe that it is not
uncommon to use i64 indexing expressions in 32-bit code (especially portable
code using int64_t), it seems reasonable to always use at least 64-bit
integers. In this way, we won't regress our analysis capabilities (and there's
a command-line option added, so experimenting with this should be easy).
As pointed out by Eli during the review, there are other potential overflow
conditions that this patch does not address. Fixing those is left to follow-up
work.
Patch by me with contributions from Michael Ferguson (mferguson@cray.com).
Differential Revision: https://reviews.llvm.org/D38662
llvm-svn: 350220
2019-01-03 00:28:09 +08:00
|
|
|
|
|
|
|
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-i128:128:128-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128-p100:128:64:64-p101:128:64:64"
|
|
|
|
|
|
|
|
|
|
|
|
; test0 is similar to SimpleCases.ll
|
|
|
|
|
|
|
|
%T = type { i32, [10 x i8] }
|
|
|
|
|
|
|
|
; CHECK: Function: test0
|
|
|
|
; CHECK-NOT: MayAlias:
|
|
|
|
define void @test0(%T addrspace(100)* %P) {
|
|
|
|
%A = getelementptr %T, %T addrspace(100)* %P, i64 0
|
|
|
|
%B = getelementptr %T, %T addrspace(100)* %P, i64 0, i32 0
|
|
|
|
%C = getelementptr %T, %T addrspace(100)* %P, i64 0, i32 1
|
|
|
|
%D = getelementptr %T, %T addrspace(100)* %P, i64 0, i32 1, i64 0
|
|
|
|
%E = getelementptr %T, %T addrspace(100)* %P, i64 0, i32 1, i64 5
|
|
|
|
ret void
|
|
|
|
}
|
|
|
|
|
|
|
|
; test1 checks that >64 bits of index can be considered.
|
|
|
|
; If BasicAA is truncating the arithmetic, it will conclude
|
|
|
|
; that %A and %B must alias when in fact they must not.
|
|
|
|
|
|
|
|
; CHECK: Function: test1
|
|
|
|
; CHECK-NOT: MustAlias:
|
|
|
|
; CHECK: NoAlias:
|
|
|
|
; CHECK-SAME: %A
|
|
|
|
; CHECK-SAME: %B
|
|
|
|
define void @test1(double addrspace(100)* %P, i128 %i) {
|
|
|
|
; 1180591620717411303424 is 2**70
|
|
|
|
; 590295810358705651712 is 2**69
|
|
|
|
%i70 = add i128 %i, 1180591620717411303424
|
|
|
|
%i69 = add i128 %i, 590295810358705651712
|
|
|
|
%A = getelementptr double, double addrspace(100)* %P, i128 %i70
|
|
|
|
%B = getelementptr double, double addrspace(100)* %P, i128 %i69
|
|
|
|
ret void
|
|
|
|
}
|
|
|
|
|
|
|
|
; test2 checks that >64 bits of index can be considered
|
|
|
|
; and computes the same address in two ways to ensure that
|
|
|
|
; they are considered equivalent.
|
|
|
|
|
|
|
|
; CHECK: Function: test2
|
|
|
|
; CHECK: MustAlias:
|
|
|
|
; CHECK-SAME: %A
|
|
|
|
; CHECK-SAME: %C
|
|
|
|
define void @test2(double addrspace(100)* %P, i128 %i) {
|
|
|
|
; 1180591620717411303424 is 2**70
|
|
|
|
; 590295810358705651712 is 2**69
|
|
|
|
%i70 = add i128 %i, 1180591620717411303424
|
|
|
|
%i69 = add i128 %i, 590295810358705651712
|
|
|
|
%j70 = add i128 %i69, 590295810358705651712
|
|
|
|
%A = getelementptr double, double addrspace(100)* %P, i128 %i70
|
|
|
|
%C = getelementptr double, double addrspace(100)* %P, i128 %j70
|
|
|
|
ret void
|
|
|
|
}
|