SDValue RV =
DAG.getNode(ISD::TRUNCATE, DL, VT, DAG.getNode(Opc, DL, PVT, NN0, NN1));
- // New replace instances of N0 and N1
- if (Replace0 && N0 && N0.getOpcode() != ISD::DELETED_NODE && NN0 &&
- NN0.getOpcode() != ISD::DELETED_NODE) {
+ // We are always replacing N0/N1's use in N and only need
+ // additional replacements if there are additional uses.
+ Replace0 &= !N0->hasOneUse();
+ Replace1 &= (N0 != N1) && !N1->hasOneUse();
+
+ // Combine Op here so it is presreved past replacements.
+ CombineTo(Op.getNode(), RV);
+
+ // If operands have a use ordering, make sur we deal with
+ // predecessor first.
+ if (Replace0 && Replace1 && N0.getNode()->isPredecessorOf(N1.getNode())) {
+ std::swap(N0, N1);
+ std::swap(NN0, NN1);
+ }
+
+ if (Replace0) {
AddToWorklist(NN0.getNode());
ReplaceLoadWithPromotedLoad(N0.getNode(), NN0.getNode());
}
-
- if (Replace1 && N1 && N1.getOpcode() != ISD::DELETED_NODE && NN1 &&
- NN1.getOpcode() != ISD::DELETED_NODE) {
+ if (Replace1) {
AddToWorklist(NN1.getNode());
ReplaceLoadWithPromotedLoad(N1.getNode(), NN1.getNode());
}
-
- // Deal with Op being deleted.
- if (Op && Op.getOpcode() != ISD::DELETED_NODE)
- return RV;
+ return Op;
}
return SDValue();
}
--- /dev/null
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu | FileCheck %s
+
+@var_3 = external global i16, align 2
+@var_13 = external global i16, align 2
+@var_212 = external global i64, align 8
+
+define void @pr34127() {
+; CHECK-LABEL: pr34127:
+; CHECK: # BB#0: # %entry
+; CHECK-NEXT: movzwl {{.*}}(%rip), %eax
+; CHECK-NEXT: movw {{.*}}(%rip), %cx
+; CHECK-NEXT: andw %ax, %cx
+; CHECK-NEXT: andl %eax, %ecx
+; CHECK-NEXT: movl %ecx, -{{[0-9]+}}(%rsp)
+; CHECK-NEXT: xorl %edx, %edx
+; CHECK-NEXT: testw %cx, %cx
+; CHECK-NEXT: sete %dl
+; CHECK-NEXT: andl %eax, %edx
+; CHECK-NEXT: movq %rdx, {{.*}}(%rip)
+; CHECK-NEXT: movw $0, (%rax)
+; CHECK-NEXT: retq
+entry:
+ %a = alloca i32, align 4
+ %0 = load i16, i16* @var_3, align 2
+ %conv = zext i16 %0 to i32
+ %1 = load i16, i16* @var_3, align 2
+ %conv1 = zext i16 %1 to i32
+ %2 = load i16, i16* @var_13, align 2
+ %conv2 = zext i16 %2 to i32
+ %and = and i32 %conv1, %conv2
+ %and3 = and i32 %conv, %and
+ store i32 %and3, i32* %a, align 4
+ %3 = load i16, i16* @var_3, align 2
+ %conv4 = zext i16 %3 to i32
+ %4 = load i16, i16* @var_3, align 2
+ %conv5 = zext i16 %4 to i32
+ %5 = load i16, i16* @var_13, align 2
+ %conv6 = zext i16 %5 to i32
+ %and7 = and i32 %conv5, %conv6
+ %and8 = and i32 %conv4, %and7
+ %tobool = icmp ne i32 %and8, 0
+ %lnot = xor i1 %tobool, true
+ %conv9 = zext i1 %lnot to i32
+ %6 = load i16, i16* @var_3, align 2
+ %conv10 = zext i16 %6 to i32
+ %and11 = and i32 %conv9, %conv10
+ %conv12 = sext i32 %and11 to i64
+ store i64 %conv12, i64* @var_212, align 8
+ %conv14 = zext i1 undef to i16
+ store i16 %conv14, i16* undef, align 2
+ ret void
+}