llvm.org GIT mirror llvm / b9ce60f
[BasicAA] Revert "Revert r218714 - Make better use of zext and sign information." This reverts r218944, which reverted r218714, plus a bug fix. Description of the bug in r218714 (by Nick) The original patch forgot to check if the Scale in VariableGEPIndex flipped the sign of the variable. The BasicAA pass iterates over the instructions in the order they appear in the function, and so BasicAliasAnalysis::aliasGEP is called with the variable it first comes across as parameter GEP1. Adding a %reorder label puts the definition of %a after %b so aliasGEP is called with %b as the first parameter and %a as the second. aliasGEP later calculates that %a == %b + 1 - %idxprom where %idxprom >= 0 (if %a was passed as the first parameter it would calculate %b == %a - 1 + %idxprom where %idxprom >= 0) - ignoring that %idxprom is scaled by -1 here lead the patch to incorrectly conclude that %a > %b. Revised patch by Nick White, thanks! Thanks to Lang to isolating the bug. Slightly modified by me to add an early exit from the loop and avoid unnecessary, but expensive, function calls. Original commit message: Two related things: 1. Fixes a bug when calculating the offset in GetLinearExpression. The code previously used zext to extend the offset, so negative offsets were converted to large positive ones. 2. Enhance aliasGEP to deduce that, if the difference between two GEP allocations is positive and all the variables that govern the offset are also positive (i.e. the offset is strictly after the higher base pointer), then locations that fit in the gap between the two base pointers are NoAlias. Patch by Nick White! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@219135 91177308-0d34-0410-b5e6-96231b3b80d8 Hal Finkel 5 years ago
3 changed file(s) with 129 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
253253 Value *Result = GetLinearExpression(CastOp, Scale, Offset, Extension,
254254 DL, Depth+1, AT, DT);
255255 Scale = Scale.zext(OldWidth);
256 Offset = Offset.zext(OldWidth);
256
257 // We have to sign-extend even if Extension == EK_ZeroExt as we can't
258 // decompose a sign extension (i.e. zext(x - 1) != zext(x) - zext(-1)).
259 Offset = Offset.sext(OldWidth);
257260
258261 return Result;
259262 }
10541057 // Grab the least significant bit set in any of the scales.
10551058 if (!GEP1VariableIndices.empty()) {
10561059 uint64_t Modulo = 0;
1057 for (unsigned i = 0, e = GEP1VariableIndices.size(); i != e; ++i)
1060 bool AllPositive = true;
1061 for (unsigned i = 0, e = GEP1VariableIndices.size();
1062 i != e && AllPositive; ++i) {
1063 const Value *V = GEP1VariableIndices[i].V;
10581064 Modulo |= (uint64_t)GEP1VariableIndices[i].Scale;
1065
1066 bool SignKnownZero, SignKnownOne;
1067 ComputeSignBit(
1068 const_cast(V),
1069 SignKnownZero, SignKnownOne,
1070 DL, 0, AT, nullptr, DT);
1071
1072 // Zero-extension widens the variable, and so forces the sign
1073 // bit to zero.
1074 bool IsZExt = GEP1VariableIndices[i].Extension == EK_ZeroExt;
1075 SignKnownZero |= IsZExt;
1076 SignKnownOne &= !IsZExt;
1077
1078 // If the variable begins with a zero then we know it's
1079 // positive, regardless of whether the value is signed or
1080 // unsigned.
1081 int64_t Scale = GEP1VariableIndices[i].Scale;
1082 AllPositive &=
1083 (SignKnownZero && Scale >= 0) ||
1084 (SignKnownOne && Scale < 0);
1085
1086 // If the Value is currently positive but could change in a cycle,
1087 // then we can't guarantee it'll always br positive.
1088 if (AllPositive && !isValueEqualInPotentialCycles(V, V))
1089 AllPositive = false;
1090 }
1091
10591092 Modulo = Modulo ^ (Modulo & (Modulo - 1));
10601093
10611094 // We can compute the difference between the two addresses
10641097 uint64_t ModOffset = (uint64_t)GEP1BaseOffset & (Modulo - 1);
10651098 if (V1Size != UnknownSize && V2Size != UnknownSize &&
10661099 ModOffset >= V2Size && V1Size <= Modulo - ModOffset)
1100 return NoAlias;
1101
1102 // If we know all the variables are positive, then GEP1 >= GEP1BasePtr.
1103 // If GEP1BasePtr > V2 (GEP1BaseOffset > 0) then we know the pointers
1104 // don't alias if V2Size can fit in the gap between V2 and GEP1BasePtr.
1105 if (AllPositive && GEP1BaseOffset > 0 && V2Size <= (uint64_t) GEP1BaseOffset)
10671106 return NoAlias;
10681107 }
10691108
3838
3939 ; CHECK-LABEL: pr18068
4040 ; CHECK: MayAlias: i32* %0, i32* %arrayidx5
41 ; CHECK: NoAlias: i32* %arrayidx13, i32* %arrayidx5
4142
4243 define i32 @pr18068(i32* %jj7, i32* %j) {
4344 entry:
0 ; RUN: opt < %s -basicaa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
1 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-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"
2 target triple = "x86_64-unknown-linux-gnu"
3
4 ; CHECK-LABEL: test_with_zext
5 ; CHECK: NoAlias: i8* %a, i8* %b
6
7 define void @test_with_zext() {
8 %1 = tail call i8* @malloc(i64 120)
9 %a = getelementptr inbounds i8* %1, i64 8
10 %2 = getelementptr inbounds i8* %1, i64 16
11 %3 = zext i32 3 to i64
12 %b = getelementptr inbounds i8* %2, i64 %3
13 ret void
14 }
15
16 ; CHECK-LABEL: test_with_lshr
17 ; CHECK: NoAlias: i8* %a, i8* %b
18
19 define void @test_with_lshr(i64 %i) {
20 %1 = tail call i8* @malloc(i64 120)
21 %a = getelementptr inbounds i8* %1, i64 8
22 %2 = getelementptr inbounds i8* %1, i64 16
23 %3 = lshr i64 %i, 2
24 %b = getelementptr inbounds i8* %2, i64 %3
25 ret void
26 }
27
28 ; CHECK-LABEL: test_with_a_loop
29 ; CHECK: NoAlias: i8* %a, i8* %b
30
31 define void @test_with_a_loop() {
32 %1 = tail call i8* @malloc(i64 120)
33 %a = getelementptr inbounds i8* %1, i64 8
34 %2 = getelementptr inbounds i8* %1, i64 16
35 br label %for.loop
36
37 for.loop:
38 %i = phi i32 [ 0, %0 ], [ %i.next, %for.loop ]
39 %3 = zext i32 %i to i64
40 %b = getelementptr inbounds i8* %2, i64 %3
41 %i.next = add nuw nsw i32 %i, 1
42 %4 = icmp eq i32 %i.next, 10
43 br i1 %4, label %for.loop.exit, label %for.loop
44
45 for.loop.exit:
46 ret void
47 }
48
49 ; CHECK-LABEL: test_sign_extension
50 ; CHECK: PartialAlias: i64* %b.i64, i8* %a
51
52 define void @test_sign_extension(i32 %p) {
53 %1 = tail call i8* @malloc(i64 120)
54 %p.64 = zext i32 %p to i64
55 %a = getelementptr inbounds i8* %1, i64 %p.64
56 %p.minus1 = add i32 %p, -1
57 %p.minus1.64 = zext i32 %p.minus1 to i64
58 %b.i8 = getelementptr inbounds i8* %1, i64 %p.minus1.64
59 %b.i64 = bitcast i8* %b.i8 to i64*
60 ret void
61 }
62
63 ; CHECK-LABEL: test_fe_tools
64 ; CHECK: PartialAlias: i32* %a, i32* %b
65
66 define void @test_fe_tools([8 x i32]* %values) {
67 br label %reorder
68
69 for.loop:
70 %i = phi i32 [ 0, %reorder ], [ %i.next, %for.loop ]
71 %idxprom = zext i32 %i to i64
72 %b = getelementptr inbounds [8 x i32]* %values, i64 0, i64 %idxprom
73 %i.next = add nuw nsw i32 %i, 1
74 %1 = icmp eq i32 %i.next, 10
75 br i1 %1, label %for.loop.exit, label %for.loop
76
77 reorder:
78 %a = getelementptr inbounds [8 x i32]* %values, i64 0, i64 1
79 br label %for.loop
80
81 for.loop.exit:
82 ret void
83 }
84
85 ; Function Attrs: nounwind
86 declare noalias i8* @malloc(i64)