From 14e29de03db7e2b075b70fdb419f7ac428381b11 Mon Sep 17 00:00:00 2001 From: Sam Parker Date: Mon, 8 Jan 2018 13:21:24 +0000 Subject: [PATCH] [DAGCombine] Fix for PR35761 I had falsely assumed that constant operands would be operand(1) of the bin ops that may need their constant operand to be masked. Bugzilla: https://bugs.llvm.org/show_bug.cgi?id=35761 Differential Revision: https://reviews.llvm.org/D41667 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@321991 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 14 ++++++--- test/CodeGen/X86/pr35761.ll | 36 ++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 4 deletions(-) create mode 100644 test/CodeGen/X86/pr35761.ll diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 1fcb010eac5..d823c455b5e 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -3923,10 +3923,16 @@ bool DAGCombiner::BackwardsPropagateMask(SDNode *N, SelectionDAG &DAG) { // Narrow any constants that need it. for (auto *LogicN : NodesWithConsts) { - auto *C = cast(LogicN->getOperand(1)); - SDValue And = DAG.getNode(ISD::AND, SDLoc(C), C->getValueType(0), - SDValue(C, 0), MaskOp); - DAG.UpdateNodeOperands(LogicN, LogicN->getOperand(0), And); + SDValue Op0 = LogicN->getOperand(0); + SDValue Op1 = LogicN->getOperand(1); + + if (isa(Op0)) + std::swap(Op0, Op1); + + SDValue And = DAG.getNode(ISD::AND, SDLoc(Op1), Op1.getValueType(), + Op1, MaskOp); + + DAG.UpdateNodeOperands(LogicN, Op0, And); } // Create narrow loads. diff --git a/test/CodeGen/X86/pr35761.ll b/test/CodeGen/X86/pr35761.ll new file mode 100644 index 00000000000..0bf81bff841 --- /dev/null +++ b/test/CodeGen/X86/pr35761.ll @@ -0,0 +1,36 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=x86_64-unknown-linux %s -o - | FileCheck %s + +@x = global i8 0, align 1 +@y = global i32 0, align 4 +@z = global i24 0, align 4 + +define void @PR35761(i32 %call) { +; CHECK-LABEL: PR35761: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movzbl {{.*}}(%rip), %eax +; CHECK-NEXT: andl $1, %eax +; CHECK-NEXT: movzbl {{.*}}(%rip), %ecx +; CHECK-NEXT: xorl $255, %ecx +; CHECK-NEXT: orl %eax, %ecx +; CHECK-NEXT: movw %cx, {{.*}}(%rip) +; CHECK-NEXT: movb $0, z+{{.*}}(%rip) +; CHECK-NEXT: retq +entry: + %0 = load i8, i8* @x, align 1 + %tobool = trunc i8 %0 to i1 + %conv = zext i1 %tobool to i32 + %or = or i32 32767, %call + %neg = xor i32 %or, -1 + %neg1 = xor i32 %neg, -1 + %1 = load i32, i32* @y, align 4 + %xor = xor i32 %neg1, %1 + %or2 = or i32 %conv, %xor + %conv3 = trunc i32 %or2 to i8 + %bf.load = load i24, i24* @z, align 4 + %2 = zext i8 %conv3 to i24 + %bf.value = and i24 %2, 4194303 + store i24 %bf.value, i24* @z, align 2 + ret void +} +