llvm.org GIT mirror llvm / def6ebb
Merging r311623: ------------------------------------------------------------------------ r311623 | hans | 2017-08-23 18:08:27 -0700 (Wed, 23 Aug 2017) | 11 lines [DAG] Fix Node Replacement in PromoteIntBinOp When one operand is a user of another in a promoted binary operation we may replace and delete the returned value before returning triggering an assertion. Reorder node replacements to prevent this. Fixes PR34137. Landing on behalf of Nirav. Differential Revision: https://reviews.llvm.org/D36581 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_50@311670 91177308-0d34-0410-b5e6-96231b3b80d8 Hans Wennborg 3 years ago
2 changed file(s) with 71 addition(s) and 10 deletion(s). Raw diff Collapse all Expand all
11171117 SDValue RV =
11181118 DAG.getNode(ISD::TRUNCATE, DL, VT, DAG.getNode(Opc, DL, PVT, NN0, NN1));
11191119
1120 // New replace instances of N0 and N1
1121 if (Replace0 && N0 && N0.getOpcode() != ISD::DELETED_NODE && NN0 &&
1122 NN0.getOpcode() != ISD::DELETED_NODE) {
1120 // We are always replacing N0/N1's use in N and only need
1121 // additional replacements if there are additional uses.
1122 Replace0 &= !N0->hasOneUse();
1123 Replace1 &= (N0 != N1) && !N1->hasOneUse();
1124
1125 // Combine Op here so it is presreved past replacements.
1126 CombineTo(Op.getNode(), RV);
1127
1128 // If operands have a use ordering, make sur we deal with
1129 // predecessor first.
1130 if (Replace0 && Replace1 && N0.getNode()->isPredecessorOf(N1.getNode())) {
1131 std::swap(N0, N1);
1132 std::swap(NN0, NN1);
1133 }
1134
1135 if (Replace0) {
11231136 AddToWorklist(NN0.getNode());
11241137 ReplaceLoadWithPromotedLoad(N0.getNode(), NN0.getNode());
11251138 }
1126
1127 if (Replace1 && N1 && N1.getOpcode() != ISD::DELETED_NODE && NN1 &&
1128 NN1.getOpcode() != ISD::DELETED_NODE) {
1139 if (Replace1) {
11291140 AddToWorklist(NN1.getNode());
11301141 ReplaceLoadWithPromotedLoad(N1.getNode(), NN1.getNode());
11311142 }
1132
1133 // Deal with Op being deleted.
1134 if (Op && Op.getOpcode() != ISD::DELETED_NODE)
1135 return RV;
1143 return Op;
11361144 }
11371145 return SDValue();
11381146 }
0 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
1 ; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu | FileCheck %s
2
3 @var_3 = external global i16, align 2
4 @var_13 = external global i16, align 2
5 @var_212 = external global i64, align 8
6
7 define void @pr34127() {
8 ; CHECK-LABEL: pr34127:
9 ; CHECK: # BB#0: # %entry
10 ; CHECK-NEXT: movzwl {{.*}}(%rip), %eax
11 ; CHECK-NEXT: movw {{.*}}(%rip), %cx
12 ; CHECK-NEXT: andw %ax, %cx
13 ; CHECK-NEXT: andl %eax, %ecx
14 ; CHECK-NEXT: movl %ecx, -{{[0-9]+}}(%rsp)
15 ; CHECK-NEXT: xorl %edx, %edx
16 ; CHECK-NEXT: testw %cx, %cx
17 ; CHECK-NEXT: sete %dl
18 ; CHECK-NEXT: andl %eax, %edx
19 ; CHECK-NEXT: movq %rdx, {{.*}}(%rip)
20 ; CHECK-NEXT: movw $0, (%rax)
21 ; CHECK-NEXT: retq
22 entry:
23 %a = alloca i32, align 4
24 %0 = load i16, i16* @var_3, align 2
25 %conv = zext i16 %0 to i32
26 %1 = load i16, i16* @var_3, align 2
27 %conv1 = zext i16 %1 to i32
28 %2 = load i16, i16* @var_13, align 2
29 %conv2 = zext i16 %2 to i32
30 %and = and i32 %conv1, %conv2
31 %and3 = and i32 %conv, %and
32 store i32 %and3, i32* %a, align 4
33 %3 = load i16, i16* @var_3, align 2
34 %conv4 = zext i16 %3 to i32
35 %4 = load i16, i16* @var_3, align 2
36 %conv5 = zext i16 %4 to i32
37 %5 = load i16, i16* @var_13, align 2
38 %conv6 = zext i16 %5 to i32
39 %and7 = and i32 %conv5, %conv6
40 %and8 = and i32 %conv4, %and7
41 %tobool = icmp ne i32 %and8, 0
42 %lnot = xor i1 %tobool, true
43 %conv9 = zext i1 %lnot to i32
44 %6 = load i16, i16* @var_3, align 2
45 %conv10 = zext i16 %6 to i32
46 %and11 = and i32 %conv9, %conv10
47 %conv12 = sext i32 %and11 to i64
48 store i64 %conv12, i64* @var_212, align 8
49 %conv14 = zext i1 undef to i16
50 store i16 %conv14, i16* undef, align 2
51 ret void
52 }