Skip to content

Commit b4939da

Browse files
committed
Add 3 LLVM patches to fix issue #19792
miscompilation of broadcast
1 parent c38a5a3 commit b4939da

File tree

4 files changed

+241
-3
lines changed

4 files changed

+241
-3
lines changed

deps/llvm.mk

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -489,17 +489,20 @@ $(eval $(call LLVM_PATCH,llvm-3.9.0_cygwin)) # R283427, Remove for 4.0
489489
endif
490490
$(eval $(call LLVM_PATCH,llvm-PR22923)) # Remove for 4.0
491491
$(eval $(call LLVM_PATCH,llvm-arm-fix-prel31))
492-
$(eval $(call LLVM_PATCH,llvm-D25865-cmakeshlib))
492+
$(eval $(call LLVM_PATCH,llvm-D25865-cmakeshlib)) # Remove for 4.0
493493
# Cygwin and openSUSE still use win32-threads mingw, https://llvm.org/bugs/show_bug.cgi?id=26365
494494
$(eval $(call LLVM_PATCH,llvm-3.9.0_threads))
495-
$(eval $(call LLVM_PATCH,llvm-3.9.0_win64-reloc-dwarf))
495+
$(eval $(call LLVM_PATCH,llvm-3.9.0_win64-reloc-dwarf)) # modified version applied as R290809, Remove for 4.0
496496
$(eval $(call LLVM_PATCH,llvm-3.9.0_D27296-libssp))
497-
$(eval $(call LLVM_PATCH,llvm-D27609-AArch64-UABS_G3))
497+
$(eval $(call LLVM_PATCH,llvm-D27609-AArch64-UABS_G3)) # Remove for 4.0
498498
$(eval $(call LLVM_PATCH,llvm-D27629-AArch64-large_model))
499499
# patches for NVPTX
500500
$(eval $(call LLVM_PATCH,llvm-D9168_argument_alignment)) # Remove for 4.0
501501
$(eval $(call LLVM_PATCH,llvm-D23597_sdag_names)) # Dep for D24300, remove for 4.0
502502
$(eval $(call LLVM_PATCH,llvm-D24300_ptx_intrinsics)) # Remove for 4.0
503+
$(eval $(call LLVM_PATCH,llvm-D27389)) # Julia issue #19792, Remove for 4.0
504+
$(eval $(call LLVM_PATCH,llvm-D27397)) # Julia issue #19792, Remove for 4.0
505+
$(eval $(call LLVM_PATCH,llvm-D28009)) # Julia issue #19792, Remove for 4.0
503506
endif # LLVM_VER
504507

505508
ifeq ($(LLVM_VER),3.7.1)

deps/patches/llvm-D27389.patch

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
commit 83dc06334ff95ad18a951d0bb540290510f2f81a
2+
Author: Keno Fischer <[email protected]>
3+
Date: Thu Dec 8 17:22:35 2016 +0000
4+
5+
ConstantFolding: Don't crash when encountering vector GEP
6+
7+
ConstantFolding tried to cast one of the scalar indices to a vector
8+
type. Instead, use the vector type only for the first index (which
9+
is the only one allowed to be a vector) and use its scalar type
10+
otherwise.
11+
12+
Fixes PR31250.
13+
14+
Reviewers: majnemer
15+
Differential Revision: https://reviews.llvm.org/D27389
16+
17+
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@289073 91177308-0d34-0410-b5e6-96231b3b80d8
18+
19+
diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp
20+
index 2d1edfe..1c0bf01a 100644
21+
--- a/lib/Analysis/ConstantFolding.cpp
22+
+++ b/lib/Analysis/ConstantFolding.cpp
23+
@@ -734,14 +734,15 @@ Constant *CastGEPIndices(Type *SrcElemTy, ArrayRef<Constant *> Ops,
24+
Type *ResultTy, Optional<unsigned> InRangeIndex,
25+
const DataLayout &DL, const TargetLibraryInfo *TLI) {
26+
Type *IntPtrTy = DL.getIntPtrType(ResultTy);
27+
+ Type *IntPtrScalarTy = IntPtrTy->getScalarType();
28+
29+
bool Any = false;
30+
SmallVector<Constant*, 32> NewIdxs;
31+
for (unsigned i = 1, e = Ops.size(); i != e; ++i) {
32+
if ((i == 1 ||
33+
- !isa<StructType>(GetElementPtrInst::getIndexedType(SrcElemTy,
34+
- Ops.slice(1, i - 1)))) &&
35+
- Ops[i]->getType() != IntPtrTy) {
36+
+ !isa<StructType>(GetElementPtrInst::getIndexedType(
37+
+ SrcElemTy, Ops.slice(1, i - 1)))) &&
38+
+ Ops[i]->getType() != (i == 1 ? IntPtrTy : IntPtrScalarTy)) {
39+
Any = true;
40+
NewIdxs.push_back(ConstantExpr::getCast(CastInst::getCastOpcode(Ops[i],
41+
true,
42+
diff --git a/test/Analysis/ConstantFolding/vectorgep-crash.ll b/test/Analysis/ConstantFolding/vectorgep-crash.ll
43+
new file mode 100644
44+
index 0000000..bcc96b2
45+
--- /dev/null
46+
+++ b/test/Analysis/ConstantFolding/vectorgep-crash.ll
47+
@@ -0,0 +1,19 @@
48+
+; RUN: opt -instcombine -S -o - %s | FileCheck %s
49+
+; Tests that we don't crash upon encountering a vector GEP
50+
+
51+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
52+
+target triple = "x86_64-unknown-linux-gnu"
53+
+
54+
+%Dual = type { %Dual.72, %Partials.73 }
55+
+%Dual.72 = type { double, %Partials }
56+
+%Partials = type { [2 x double] }
57+
+%Partials.73 = type { [2 x %Dual.72] }
58+
+
59+
+; Function Attrs: sspreq
60+
+define <8 x i64*> @"julia_axpy!_65480"(%Dual* %arg1, <8 x i64> %arg2) {
61+
+top:
62+
+; CHECK: %VectorGep14 = getelementptr inbounds %Dual, %Dual* %arg1, <8 x i64> %arg2, i32 1, i32 0, i64 0, i32 1, i32 0, i64 0
63+
+ %VectorGep14 = getelementptr inbounds %Dual, %Dual* %arg1, <8 x i64> %arg2, i32 1, i32 0, i64 0, i32 1, i32 0, i64 0
64+
+ %0 = bitcast <8 x double*> %VectorGep14 to <8 x i64*>
65+
+ ret <8 x i64*> %0
66+
+}

deps/patches/llvm-D27397.patch

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
commit 99ca52276f9ee1386866d6dff6179cfa64824621
2+
Author: Keno Fischer <[email protected]>
3+
Date: Mon Dec 5 21:25:03 2016 +0000
4+
5+
[LAA] Prevent invalid IR for loop-invariant bound in loop body
6+
7+
Summary:
8+
If LAA expands a bound that is loop invariant, but not hoisted out
9+
of the loop body, it used to use that value anyway, causing a
10+
non-domination error, because the memcheck block is of course not
11+
dominated by the scalar loop body. Detect this situation and expand
12+
the SCEV expression instead.
13+
14+
Fixes PR31251
15+
16+
Reviewers: anemet
17+
Subscribers: mzolotukhin, llvm-commits
18+
19+
Differential Revision: https://reviews.llvm.org/D27397
20+
21+
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@288705 91177308-0d34-0410-b5e6-96231b3b80d8
22+
23+
diff --git a/lib/Analysis/LoopAccessAnalysis.cpp b/lib/Analysis/LoopAccessAnalysis.cpp
24+
index 01a2f46..2f3dca3 100644
25+
--- a/lib/Analysis/LoopAccessAnalysis.cpp
26+
+++ b/lib/Analysis/LoopAccessAnalysis.cpp
27+
@@ -1870,18 +1870,24 @@ expandBounds(const RuntimePointerChecking::CheckingPtrGroup *CG, Loop *TheLoop,
28+
Value *Ptr = PtrRtChecking.Pointers[CG->Members[0]].PointerValue;
29+
const SCEV *Sc = SE->getSCEV(Ptr);
30+
31+
+ unsigned AS = Ptr->getType()->getPointerAddressSpace();
32+
+ LLVMContext &Ctx = Loc->getContext();
33+
+
34+
+ // Use this type for pointer arithmetic.
35+
+ Type *PtrArithTy = Type::getInt8PtrTy(Ctx, AS);
36+
+
37+
if (SE->isLoopInvariant(Sc, TheLoop)) {
38+
DEBUG(dbgs() << "LAA: Adding RT check for a loop invariant ptr:" << *Ptr
39+
<< "\n");
40+
- return {Ptr, Ptr};
41+
+ // Ptr could be in the loop body. If so, expand a new one at the correct
42+
+ // location.
43+
+ Instruction *Inst = dyn_cast<Instruction>(Ptr);
44+
+ Value *NewPtr = (Inst && TheLoop->contains(Inst))
45+
+ ? Exp.expandCodeFor(Sc, PtrArithTy, Loc)
46+
+ : Ptr;
47+
+ return {NewPtr, NewPtr};
48+
} else {
49+
- unsigned AS = Ptr->getType()->getPointerAddressSpace();
50+
- LLVMContext &Ctx = Loc->getContext();
51+
-
52+
- // Use this type for pointer arithmetic.
53+
- Type *PtrArithTy = Type::getInt8PtrTy(Ctx, AS);
54+
Value *Start = nullptr, *End = nullptr;
55+
-
56+
DEBUG(dbgs() << "LAA: Adding RT check for range:\n");
57+
Start = Exp.expandCodeFor(CG->Low, PtrArithTy, Loc);
58+
End = Exp.expandCodeFor(CG->High, PtrArithTy, Loc);
59+
diff --git a/test/Transforms/LoopVersioning/loop-invariant-bound.ll b/test/Transforms/LoopVersioning/loop-invariant-bound.ll
60+
new file mode 100644
61+
index 0000000..3411adb
62+
--- /dev/null
63+
+++ b/test/Transforms/LoopVersioning/loop-invariant-bound.ll
64+
@@ -0,0 +1,37 @@
65+
+; RUN: opt -loop-versioning -S < %s | FileCheck %s
66+
+; Checks that when introducing check, we don't accidentally introduce non-dominating instructions
67+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
68+
+
69+
+%Dual.212 = type { %Dual.213, %Partials.215 }
70+
+%Dual.213 = type { double, %Partials.214 }
71+
+%Partials.214 = type { [2 x double] }
72+
+%Partials.215 = type { [2 x %Dual.213] }
73+
+
74+
+; Function Attrs: sspreq
75+
+define void @"julia_axpy!_65480"(%Dual.212*) {
76+
+top:
77+
+ br label %if24
78+
+
79+
+; CHECK-NOT: %bc = bitcast i64* %v2.sroa.0.0..sroa_cast
80+
+; CHECK: %bound0
81+
+
82+
+if24: ; preds = %if24, %top
83+
+ %"#temp#1.sroa.3.02" = phi i64 [ undef, %top ], [ %2, %if24 ]
84+
+ %"#temp#1.sroa.0.01" = phi i64 [ undef, %top ], [ %1, %if24 ]
85+
+ %1 = add i64 %"#temp#1.sroa.0.01", 1
86+
+ %2 = add i64 %"#temp#1.sroa.3.02", 1
87+
+ ; This pointer is loop invariant. LAA used to re-use it from memcheck, even though it didn't dominate.
88+
+ %v2.sroa.0.0..sroa_cast = bitcast %Dual.212* %0 to i64*
89+
+ %v2.sroa.0.0.copyload = load i64, i64* %v2.sroa.0.0..sroa_cast, align 1
90+
+ %3 = add i64 %"#temp#1.sroa.0.01", -1
91+
+ %4 = getelementptr inbounds %Dual.212, %Dual.212* undef, i64 %3, i32 1, i32 0, i64 0, i32 1, i32 0, i64 0
92+
+ %5 = bitcast double* %4 to i64*
93+
+ store i64 undef, i64* %5, align 8
94+
+ %notlhs27 = icmp eq i64 %2, undef
95+
+ %notrhs28 = icmp eq i64 %1, undef
96+
+ %6 = or i1 %notrhs28, %notlhs27
97+
+ br i1 %6, label %L41.L335_crit_edge, label %if24
98+
+
99+
+L41.L335_crit_edge: ; preds = %if24
100+
+ ret void
101+
+}

deps/patches/llvm-D28009.patch

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
commit 57ab82784ddb8d21eb0041d52f8490d8fd404e29
2+
Author: Michael Kuperstein <[email protected]>
3+
Date: Wed Dec 21 17:34:21 2016 +0000
4+
5+
[ConstantFolding] Fix vector GEPs harder
6+
7+
For vector GEPs, CastGEPIndices can end up in an infinite recursion, because
8+
we compare the vector type to the scalar pointer type, find them different,
9+
and then try to cast a type to itself.
10+
11+
Differential Revision: https://reviews.llvm.org/D28009
12+
13+
14+
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@290260 91177308-0d34-0410-b5e6-96231b3b80d8
15+
16+
diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp
17+
index cf0d5e4..9e521e1 100644
18+
--- a/lib/Analysis/ConstantFolding.cpp
19+
+++ b/lib/Analysis/ConstantFolding.cpp
20+
@@ -742,13 +742,16 @@ Constant *CastGEPIndices(Type *SrcElemTy, ArrayRef<Constant *> Ops,
21+
if ((i == 1 ||
22+
!isa<StructType>(GetElementPtrInst::getIndexedType(
23+
SrcElemTy, Ops.slice(1, i - 1)))) &&
24+
- Ops[i]->getType() != (i == 1 ? IntPtrTy : IntPtrScalarTy)) {
25+
+ Ops[i]->getType()->getScalarType() != IntPtrScalarTy) {
26+
Any = true;
27+
+ Type *NewType = Ops[i]->getType()->isVectorTy()
28+
+ ? IntPtrTy
29+
+ : IntPtrTy->getScalarType();
30+
NewIdxs.push_back(ConstantExpr::getCast(CastInst::getCastOpcode(Ops[i],
31+
true,
32+
- IntPtrTy,
33+
+ NewType,
34+
true),
35+
- Ops[i], IntPtrTy));
36+
+ Ops[i], NewType));
37+
} else
38+
NewIdxs.push_back(Ops[i]);
39+
}
40+
diff --git a/test/Analysis/ConstantFolding/vectorgep-crash.ll b/test/Analysis/ConstantFolding/vectorgep-crash.ll
41+
index bcc96b2..e7a5117 100644
42+
--- a/test/Analysis/ConstantFolding/vectorgep-crash.ll
43+
+++ b/test/Analysis/ConstantFolding/vectorgep-crash.ll
44+
@@ -17,3 +17,24 @@ top:
45+
%0 = bitcast <8 x double*> %VectorGep14 to <8 x i64*>
46+
ret <8 x i64*> %0
47+
}
48+
+
49+
+%struct.A = type { i32, %struct.B* }
50+
+%struct.B = type { i64, %struct.C* }
51+
+%struct.C = type { i64 }
52+
+
53+
+@G = internal global [65 x %struct.A] zeroinitializer, align 16
54+
+; CHECK-LABEL: @test
55+
+; CHECK: ret <16 x i32*> getelementptr ([65 x %struct.A], [65 x %struct.A]* @G, <16 x i64> zeroinitializer, <16 x i64> <i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7, i64 8, i64 9, i64 10, i64 11, i64 12, i64 13, i64 14, i64 15, i64 16>, <16 x i32> zeroinitializer)
56+
+define <16 x i32*> @test() {
57+
+vector.body:
58+
+ %VectorGep = getelementptr [65 x %struct.A], [65 x %struct.A]* @G, <16 x i64> zeroinitializer, <16 x i64> <i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7, i64 8, i64 9, i64 10, i64 11, i64 12, i64 13, i64 14, i64 15, i64 16>, <16 x i32> zeroinitializer
59+
+ ret <16 x i32*> %VectorGep
60+
+}
61+
+
62+
+; CHECK-LABEL: @test2
63+
+; CHECK: ret <16 x i32*> getelementptr ([65 x %struct.A], [65 x %struct.A]* @G, <16 x i64> zeroinitializer, <16 x i64> <i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7, i64 8, i64 9,
64+
+define <16 x i32*> @test2() {
65+
+vector.body:
66+
+ %VectorGep = getelementptr [65 x %struct.A], [65 x %struct.A]* @G, <16 x i32> zeroinitializer, <16 x i64> <i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7, i64 8, i64 9, i64 10, i64 11, i64 12, i64 13, i64 14, i64 15, i64 16>, <16 x i32> zeroinitializer
67+
+ ret <16 x i32*> %VectorGep
68+
+}

0 commit comments

Comments
 (0)