Skip to content

Commit 45f8e6f

Browse files
authored
Merge pull request #403 from vchuravy/vc/lvvm9-missing
Add missing LLVM patches
2 parents 82e0a3c + ebb88ea commit 45f8e6f

6 files changed

+383
-0
lines changed
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
From 4c7e1defbddafcfcfe1211b041d43a36114a8f48 Mon Sep 17 00:00:00 2001
2+
From: Valentin Churavy <v.churavy@gmail.com>
3+
Date: Sat, 14 Dec 2019 10:33:30 -0500
4+
Subject: [PATCH 2/2] [CodegenPrepare] Guard against degenerate branches
5+
6+
Summary:
7+
Guard against a potential crash observed in https://github.com/JuliaLang/julia/issues/32994#issuecomment-524249628
8+
If two branches are collapsed we can encounter a degenerate conditional branch `TBB==FBB`.
9+
The subsequent code assumes that they differ, so we exit out early.
10+
11+
Reviewers: ributzka, spatel
12+
13+
Subscribers: loladiro, dexonsmith, hiraditya, llvm-commits
14+
15+
Tags: #llvm
16+
17+
Differential Revision: https://reviews.llvm.org/D66657
18+
---
19+
llvm/lib/CodeGen/CodeGenPrepare.cpp | 4 ++++
20+
.../CodeGen/X86/codegen-prepare-collapse.ll | 18 ++++++++++++++++++
21+
2 files changed, 22 insertions(+)
22+
create mode 100644 llvm/test/CodeGen/X86/codegen-prepare-collapse.ll
23+
24+
diff --git a/lib/CodeGen/CodeGenPrepare.cpp b/lib/CodeGen/CodeGenPrepare.cpp
25+
index c35f8666fa3..3647641c594 100644
26+
--- a/lib/CodeGen/CodeGenPrepare.cpp
27+
+++ b/lib/CodeGen/CodeGenPrepare.cpp
28+
@@ -6929,6 +6929,10 @@ bool CodeGenPrepare::splitBranchCondition(Function &F) {
29+
if (Br1->getMetadata(LLVMContext::MD_unpredictable))
30+
continue;
31+
32+
+ // The merging of mostly empty BB can cause a degenerate branch.
33+
+ if (TBB == FBB)
34+
+ continue;
35+
+
36+
unsigned Opc;
37+
Value *Cond1, *Cond2;
38+
if (match(LogicOp, m_And(m_OneUse(m_Value(Cond1)),
39+
diff --git a/test/CodeGen/X86/codegen-prepare-collapse.ll b/test/CodeGen/X86/codegen-prepare-collapse.ll
40+
new file mode 100644
41+
index 00000000000..18e3ef7afbd
42+
--- /dev/null
43+
+++ b/test/CodeGen/X86/codegen-prepare-collapse.ll
44+
@@ -0,0 +1,18 @@
45+
+; RUN: llc -fast-isel=true -O1 -mtriple=x86_64-unkown-linux-gnu -start-before=codegenprepare -stop-after=codegenprepare -o - < %s | FileCheck %s
46+
+
47+
+; CHECK-LABEL: @foo
48+
+define void @foo() {
49+
+top:
50+
+; CHECK: br label %L34
51+
+ br label %L34
52+
+
53+
+L34: ; preds = %L34, %L34, %top
54+
+ %.sroa.075.0 = phi i64 [ undef, %top ], [ undef, %L34 ], [ undef, %L34 ]
55+
+ %0 = icmp sgt i8 undef, -1
56+
+ %cond5896 = icmp eq i8 0, 2
57+
+ %cond58 = and i1 %cond5896, %0
58+
+; During codegenprepare such degenerate branches can occur and should not
59+
+; lead to crashes.
60+
+; CHECK: br label %L34
61+
+ br i1 %cond58, label %L34, label %L34
62+
+}
63+
--
64+
2.24.1
65+
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
From 7c30e23f115ae285b497ef11af0153703111dff2 Mon Sep 17 00:00:00 2001
2+
From: Valentin Churavy <v.churavy@gmail.com>
3+
Date: Sun, 22 Dec 2019 14:25:50 -0500
4+
Subject: [PATCH 1/2] [SelectionDAG] Copy FP flags when visiting a binary
5+
instruction.
6+
7+
Summary:
8+
We noticed in Julia that the sequence below no longer turned into
9+
a sequence of FMA instructions in LLVM 7+, but it did in LLVM 6.
10+
11+
```
12+
%29 = fmul contract <4 x double> %wide.load, %wide.load16
13+
%30 = fmul contract <4 x double> %wide.load13, %wide.load17
14+
%31 = fmul contract <4 x double> %wide.load14, %wide.load18
15+
%32 = fmul contract <4 x double> %wide.load15, %wide.load19
16+
%33 = fadd fast <4 x double> %vec.phi, %29
17+
%34 = fadd fast <4 x double> %vec.phi10, %30
18+
%35 = fadd fast <4 x double> %vec.phi11, %31
19+
%36 = fadd fast <4 x double> %vec.phi12, %32
20+
```
21+
22+
Unlike Clang, Julia doesn't set the `unsafe-fp-math=true` function
23+
attribute, but rather emits more local instruction flags.
24+
25+
This partially undoes https://reviews.llvm.org/D46854 and if required I can try to minimize the test further.
26+
27+
Reviewers: spatel, mcberg2017
28+
29+
Reviewed By: spatel
30+
31+
Subscribers: chriselrod, merge_guards_bot, hiraditya, llvm-commits
32+
33+
Tags: #llvm
34+
35+
Differential Revision: https://reviews.llvm.org/D71495
36+
---
37+
.../SelectionDAG/SelectionDAGBuilder.cpp | 7 +++++
38+
llvm/test/CodeGen/X86/fmf-reduction.ll | 26 +++++++++++++++++++
39+
2 files changed, 33 insertions(+)
40+
create mode 100644 llvm/test/CodeGen/X86/fmf-reduction.ll
41+
42+
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
43+
index bfeb3d1bc2b..e6362c19691 100644
44+
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
45+
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
46+
@@ -2833,6 +2833,13 @@ void SelectionDAGBuilder::visitBinary(const User &I, unsigned Opcode) {
47+
if (isVectorReductionOp(&I)) {
48+
Flags.setVectorReduction(true);
49+
LLVM_DEBUG(dbgs() << "Detected a reduction operation:" << I << "\n");
50+
+
51+
+ // If no flags are set we will propagate the incoming flags, if any flags
52+
+ // are set, we will intersect them with the incoming flag and so we need to
53+
+ // copy the FMF flags here.
54+
+ if (auto *FPOp = dyn_cast<FPMathOperator>(&I)) {
55+
+ Flags.copyFMF(*FPOp);
56+
+ }
57+
}
58+
59+
SDValue Op1 = getValue(I.getOperand(0));
60+
diff --git a/test/CodeGen/X86/fmf-reduction.ll b/test/CodeGen/X86/fmf-reduction.ll
61+
new file mode 100644
62+
index 00000000000..1d669d2a924
63+
--- /dev/null
64+
+++ b/test/CodeGen/X86/fmf-reduction.ll
65+
@@ -0,0 +1,26 @@
66+
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
67+
+; RUN: llc < %s -mtriple=x86_64-- -mattr=fma | FileCheck %s
68+
+
69+
+; Propagation of IR FMF should not drop flags when adding the DAG reduction flag.
70+
+; This should include an FMA instruction, not separate FMUL/FADD.
71+
+
72+
+define double @julia_dotf(<4 x double> %x, <4 x double> %y, <4 x double> %z, i1 %t3) {
73+
+; CHECK-LABEL: julia_dotf:
74+
+; CHECK: # %bb.0:
75+
+; CHECK-NEXT: vfmadd213pd {{.*#+}} ymm0 = (ymm1 * ymm0) + ymm2
76+
+; CHECK-NEXT: vextractf128 $1, %ymm0, %xmm1
77+
+; CHECK-NEXT: vaddpd %xmm1, %xmm0, %xmm0
78+
+; CHECK-NEXT: vpermilpd {{.*#+}} xmm1 = xmm0[1,0]
79+
+; CHECK-NEXT: vaddsd %xmm1, %xmm0, %xmm0
80+
+; CHECK-NEXT: vzeroupper
81+
+; CHECK-NEXT: retq
82+
+ %t1 = fmul contract <4 x double> %x, %y
83+
+ %t2 = fadd fast <4 x double> %z, %t1
84+
+ %rdx.shuf = shufflevector <4 x double> %t2, <4 x double> undef, <4 x i32> <i32 2, i32 3, i32 undef, i32 undef>
85+
+ %bin.rdx22 = fadd fast <4 x double> %t2, %rdx.shuf
86+
+ %rdx.shuf23 = shufflevector <4 x double> %bin.rdx22, <4 x double> undef, <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef>
87+
+ %bin.rdx24 = fadd fast <4 x double> %bin.rdx22, %rdx.shuf23
88+
+ %t4 = extractelement <4 x double> %bin.rdx24, i32 0
89+
+ ret double %t4
90+
+}
91+
+
92+
--
93+
2.24.1
94+

L/LLVM/v9/build_tarballs.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ version = v"9.0.1"
22

33
include("../common.jl")
44

5+
56
platforms = expand_cxxstring_abis(supported_platforms())
67
sources, script, products = configure(version, assert=false)
78
build_tarballs(ARGS, "LLVM", version, sources, script,
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
From 4c7e1defbddafcfcfe1211b041d43a36114a8f48 Mon Sep 17 00:00:00 2001
2+
From: Valentin Churavy <v.churavy@gmail.com>
3+
Date: Sat, 14 Dec 2019 10:33:30 -0500
4+
Subject: [PATCH 2/2] [CodegenPrepare] Guard against degenerate branches
5+
6+
Summary:
7+
Guard against a potential crash observed in https://github.com/JuliaLang/julia/issues/32994#issuecomment-524249628
8+
If two branches are collapsed we can encounter a degenerate conditional branch `TBB==FBB`.
9+
The subsequent code assumes that they differ, so we exit out early.
10+
11+
Reviewers: ributzka, spatel
12+
13+
Subscribers: loladiro, dexonsmith, hiraditya, llvm-commits
14+
15+
Tags: #llvm
16+
17+
Differential Revision: https://reviews.llvm.org/D66657
18+
---
19+
llvm/lib/CodeGen/CodeGenPrepare.cpp | 4 ++++
20+
.../CodeGen/X86/codegen-prepare-collapse.ll | 18 ++++++++++++++++++
21+
2 files changed, 22 insertions(+)
22+
create mode 100644 llvm/test/CodeGen/X86/codegen-prepare-collapse.ll
23+
24+
diff --git a/lib/CodeGen/CodeGenPrepare.cpp b/lib/CodeGen/CodeGenPrepare.cpp
25+
index c35f8666fa3..3647641c594 100644
26+
--- a/lib/CodeGen/CodeGenPrepare.cpp
27+
+++ b/lib/CodeGen/CodeGenPrepare.cpp
28+
@@ -6929,6 +6929,10 @@ bool CodeGenPrepare::splitBranchCondition(Function &F) {
29+
if (Br1->getMetadata(LLVMContext::MD_unpredictable))
30+
continue;
31+
32+
+ // The merging of mostly empty BB can cause a degenerate branch.
33+
+ if (TBB == FBB)
34+
+ continue;
35+
+
36+
unsigned Opc;
37+
Value *Cond1, *Cond2;
38+
if (match(LogicOp, m_And(m_OneUse(m_Value(Cond1)),
39+
diff --git a/test/CodeGen/X86/codegen-prepare-collapse.ll b/test/CodeGen/X86/codegen-prepare-collapse.ll
40+
new file mode 100644
41+
index 00000000000..18e3ef7afbd
42+
--- /dev/null
43+
+++ b/test/CodeGen/X86/codegen-prepare-collapse.ll
44+
@@ -0,0 +1,18 @@
45+
+; RUN: llc -fast-isel=true -O1 -mtriple=x86_64-unkown-linux-gnu -start-before=codegenprepare -stop-after=codegenprepare -o - < %s | FileCheck %s
46+
+
47+
+; CHECK-LABEL: @foo
48+
+define void @foo() {
49+
+top:
50+
+; CHECK: br label %L34
51+
+ br label %L34
52+
+
53+
+L34: ; preds = %L34, %L34, %top
54+
+ %.sroa.075.0 = phi i64 [ undef, %top ], [ undef, %L34 ], [ undef, %L34 ]
55+
+ %0 = icmp sgt i8 undef, -1
56+
+ %cond5896 = icmp eq i8 0, 2
57+
+ %cond58 = and i1 %cond5896, %0
58+
+; During codegenprepare such degenerate branches can occur and should not
59+
+; lead to crashes.
60+
+; CHECK: br label %L34
61+
+ br i1 %cond58, label %L34, label %L34
62+
+}
63+
--
64+
2.24.1
65+
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
From 7c30e23f115ae285b497ef11af0153703111dff2 Mon Sep 17 00:00:00 2001
2+
From: Valentin Churavy <v.churavy@gmail.com>
3+
Date: Sun, 22 Dec 2019 14:25:50 -0500
4+
Subject: [PATCH 1/2] [SelectionDAG] Copy FP flags when visiting a binary
5+
instruction.
6+
7+
Summary:
8+
We noticed in Julia that the sequence below no longer turned into
9+
a sequence of FMA instructions in LLVM 7+, but it did in LLVM 6.
10+
11+
```
12+
%29 = fmul contract <4 x double> %wide.load, %wide.load16
13+
%30 = fmul contract <4 x double> %wide.load13, %wide.load17
14+
%31 = fmul contract <4 x double> %wide.load14, %wide.load18
15+
%32 = fmul contract <4 x double> %wide.load15, %wide.load19
16+
%33 = fadd fast <4 x double> %vec.phi, %29
17+
%34 = fadd fast <4 x double> %vec.phi10, %30
18+
%35 = fadd fast <4 x double> %vec.phi11, %31
19+
%36 = fadd fast <4 x double> %vec.phi12, %32
20+
```
21+
22+
Unlike Clang, Julia doesn't set the `unsafe-fp-math=true` function
23+
attribute, but rather emits more local instruction flags.
24+
25+
This partially undoes https://reviews.llvm.org/D46854 and if required I can try to minimize the test further.
26+
27+
Reviewers: spatel, mcberg2017
28+
29+
Reviewed By: spatel
30+
31+
Subscribers: chriselrod, merge_guards_bot, hiraditya, llvm-commits
32+
33+
Tags: #llvm
34+
35+
Differential Revision: https://reviews.llvm.org/D71495
36+
---
37+
.../SelectionDAG/SelectionDAGBuilder.cpp | 7 +++++
38+
llvm/test/CodeGen/X86/fmf-reduction.ll | 26 +++++++++++++++++++
39+
2 files changed, 33 insertions(+)
40+
create mode 100644 llvm/test/CodeGen/X86/fmf-reduction.ll
41+
42+
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
43+
index bfeb3d1bc2b..e6362c19691 100644
44+
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
45+
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
46+
@@ -2833,6 +2833,13 @@ void SelectionDAGBuilder::visitBinary(const User &I, unsigned Opcode) {
47+
if (isVectorReductionOp(&I)) {
48+
Flags.setVectorReduction(true);
49+
LLVM_DEBUG(dbgs() << "Detected a reduction operation:" << I << "\n");
50+
+
51+
+ // If no flags are set we will propagate the incoming flags, if any flags
52+
+ // are set, we will intersect them with the incoming flag and so we need to
53+
+ // copy the FMF flags here.
54+
+ if (auto *FPOp = dyn_cast<FPMathOperator>(&I)) {
55+
+ Flags.copyFMF(*FPOp);
56+
+ }
57+
}
58+
59+
SDValue Op1 = getValue(I.getOperand(0));
60+
diff --git a/test/CodeGen/X86/fmf-reduction.ll b/test/CodeGen/X86/fmf-reduction.ll
61+
new file mode 100644
62+
index 00000000000..1d669d2a924
63+
--- /dev/null
64+
+++ b/test/CodeGen/X86/fmf-reduction.ll
65+
@@ -0,0 +1,26 @@
66+
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
67+
+; RUN: llc < %s -mtriple=x86_64-- -mattr=fma | FileCheck %s
68+
+
69+
+; Propagation of IR FMF should not drop flags when adding the DAG reduction flag.
70+
+; This should include an FMA instruction, not separate FMUL/FADD.
71+
+
72+
+define double @julia_dotf(<4 x double> %x, <4 x double> %y, <4 x double> %z, i1 %t3) {
73+
+; CHECK-LABEL: julia_dotf:
74+
+; CHECK: # %bb.0:
75+
+; CHECK-NEXT: vfmadd213pd {{.*#+}} ymm0 = (ymm1 * ymm0) + ymm2
76+
+; CHECK-NEXT: vextractf128 $1, %ymm0, %xmm1
77+
+; CHECK-NEXT: vaddpd %xmm1, %xmm0, %xmm0
78+
+; CHECK-NEXT: vpermilpd {{.*#+}} xmm1 = xmm0[1,0]
79+
+; CHECK-NEXT: vaddsd %xmm1, %xmm0, %xmm0
80+
+; CHECK-NEXT: vzeroupper
81+
+; CHECK-NEXT: retq
82+
+ %t1 = fmul contract <4 x double> %x, %y
83+
+ %t2 = fadd fast <4 x double> %z, %t1
84+
+ %rdx.shuf = shufflevector <4 x double> %t2, <4 x double> undef, <4 x i32> <i32 2, i32 3, i32 undef, i32 undef>
85+
+ %bin.rdx22 = fadd fast <4 x double> %t2, %rdx.shuf
86+
+ %rdx.shuf23 = shufflevector <4 x double> %bin.rdx22, <4 x double> undef, <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef>
87+
+ %bin.rdx24 = fadd fast <4 x double> %bin.rdx22, %rdx.shuf23
88+
+ %t4 = extractelement <4 x double> %bin.rdx24, i32 0
89+
+ ret double %t4
90+
+}
91+
+
92+
--
93+
2.24.1
94+
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
diff --git a/llvm/lib/Transforms/Utils/VNCoercion.cpp b/llvm/lib/Transforms/Utils/VNCoercion.cpp
2+
--- a/llvm/lib/Transforms/Utils/VNCoercion.cpp
3+
+++ b/llvm/lib/Transforms/Utils/VNCoercion.cpp
4+
@@ -34,17 +34,22 @@
5+
if (StoreSize < DL.getTypeSizeInBits(LoadTy))
6+
return false;
7+
8+
+ bool StoredNI = DL.isNonIntegralPointerType(StoredTy->getScalarType());
9+
+ bool LoadNI = DL.isNonIntegralPointerType(LoadTy->getScalarType());
10+
// Don't coerce non-integral pointers to integers or vice versa.
11+
- if (DL.isNonIntegralPointerType(StoredVal->getType()->getScalarType()) !=
12+
- DL.isNonIntegralPointerType(LoadTy->getScalarType())) {
13+
+ if (StoredNI != LoadNI) {
14+
// As a special case, allow coercion of memset used to initialize
15+
// an array w/null. Despite non-integral pointers not generally having a
16+
// specific bit pattern, we do assume null is zero.
17+
if (auto *CI = dyn_cast<Constant>(StoredVal))
18+
return CI->isNullValue();
19+
return false;
20+
+ } else if (StoredNI && LoadNI &&
21+
+ cast<PointerType>(StoredTy)->getAddressSpace() !=
22+
+ cast<PointerType>(LoadTy)->getAddressSpace()) {
23+
+ return false;
24+
}
25+
-
26+
+
27+
return true;
28+
}
29+
30+
diff --git a/llvm/test/Transforms/GVN/non-integral-pointers.ll b/llvm/test/Transforms/GVN/non-integral-pointers.ll
31+
--- a/llvm/test/Transforms/GVN/non-integral-pointers.ll
32+
+++ b/llvm/test/Transforms/GVN/non-integral-pointers.ll
33+
@@ -1,7 +1,7 @@
34+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
35+
; RUN: opt -gvn -S < %s | FileCheck %s
36+
37+
-target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128-ni:4"
38+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128-ni:4:5"
39+
target triple = "x86_64-unknown-linux-gnu"
40+
41+
define void @f0(i1 %alwaysFalse, i64 %val, i64* %loc) {
42+
@@ -285,3 +285,21 @@
43+
%ref = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* %loc.off
44+
ret i8 addrspace(4)* %ref
45+
}
46+
+
47+
+ define i8 addrspace(5)* @multini(i1 %alwaysFalse, i8 addrspace(4)* %val, i8 addrspace(4)** %loc) {
48+
+ ; CHECK-LABEL: @multini(
49+
+ ; CHECK-NOT: inttoptr
50+
+ ; CHECK-NOT: ptrtoint
51+
+ ; CHECK-NOT: addrspacecast
52+
+ entry:
53+
+ store i8 addrspace(4)* %val, i8 addrspace(4)** %loc
54+
+ br i1 %alwaysFalse, label %neverTaken, label %alwaysTaken
55+
+
56+
+ neverTaken:
57+
+ %loc.bc = bitcast i8 addrspace(4)** %loc to i8 addrspace(5)**
58+
+ %differentas = load i8 addrspace(5)*, i8 addrspace(5)** %loc.bc
59+
+ ret i8 addrspace(5)* %differentas
60+
+
61+
+ alwaysTaken:
62+
+ ret i8 addrspace(5)* null
63+
+ }
64+

0 commit comments

Comments
 (0)