diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 6eb8853550a1..dba27af5786e 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -4775,8 +4775,10 @@ bool SelectionDAG::isKnownToBeAPowerOfTwo(SDValue Val, // If x != 0: // x & -x -> non-zero pow2 // so if we find the pattern return whether we know `x` is non-zero. - SDValue X; - if (sd_match(Val, m_And(m_Value(X), m_Neg(m_Deferred(X))))) + SDValue X, Z; + if (sd_match(Val, m_And(m_Value(X), m_Neg(m_Deferred(X)))) || + (sd_match(Val, m_And(m_Value(X), m_Sub(m_Value(Z), m_Deferred(X)))) && + MaskedVectorIsZero(Z, DemandedElts, Depth + 1))) return OrZero || isKnownNeverZero(X, DemandedElts, Depth); break; } @@ -4803,10 +4805,10 @@ bool SelectionDAG::isKnownToBeAPowerOfTwo(SDValue Val, Depth + 1); } - case ISD::TRUNCATE: { - return (OrZero || isKnownNeverZero(Val, Depth)) && - isKnownToBeAPowerOfTwo(Val.getOperand(0), OrZero, Depth + 1); - } + case ISD::TRUNCATE: + return (OrZero || isKnownNeverZero(Val, DemandedElts, Depth)) && + isKnownToBeAPowerOfTwo(Val.getOperand(0), DemandedElts, OrZero, + Depth + 1); case ISD::ROTL: case ISD::ROTR: diff --git a/llvm/test/CodeGen/X86/known-pow2.ll b/llvm/test/CodeGen/X86/known-pow2.ll index 9e71dd890f81..47bf4e348e26 100644 --- a/llvm/test/CodeGen/X86/known-pow2.ll +++ b/llvm/test/CodeGen/X86/known-pow2.ll @@ -1373,14 +1373,13 @@ define i8 @pow2_trunc_vec(i8 %x8, <4 x i32> %a, ptr %p) { ; CHECK-NEXT: movdqa {{.*#+}} xmm1 = [0,4294967295,4294967295,4294967295] ; CHECK-NEXT: psubd %xmm0, %xmm1 ; CHECK-NEXT: pand %xmm0, %xmm1 -; CHECK-NEXT: movd %xmm1, %ecx +; CHECK-NEXT: movd %xmm1, %eax ; CHECK-NEXT: pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1 ; CHECK-NEXT: packuswb %xmm1, %xmm1 ; CHECK-NEXT: packuswb %xmm1, %xmm1 ; CHECK-NEXT: movd %xmm1, (%rsi) -; CHECK-NEXT: movzbl %dil, %eax -; CHECK-NEXT: divb %cl -; CHECK-NEXT: movzbl %ah, %eax +; CHECK-NEXT: decb %al +; CHECK-NEXT: andb %dil, %al ; CHECK-NEXT: # kill: def $al killed $al killed $eax ; CHECK-NEXT: retq %a.neg = sub <4 x i32> , %a