Index: lib/Analysis/ValueTracking.cpp =================================================================== --- lib/Analysis/ValueTracking.cpp +++ lib/Analysis/ValueTracking.cpp @@ -2519,18 +2519,24 @@ break; assert((!isa(U->getOperand(0)) || - !isa(U->getOperand(1))) - && "Should have simplified shuffle with 2 undef inputs"); + !isa(U->getOperand(1))) && + "Should have simplified shuffle with 2 undef inputs"); - // Look through shuffle of 1 source vector. - if (isa(U->getOperand(0))) - return ComputeNumSignBits(U->getOperand(1), Depth + 1, Q); - if (isa(U->getOperand(1))) - return ComputeNumSignBits(U->getOperand(0), Depth + 1, Q); - - // TODO: We can look through shuffles of 2 sources by computing the minimum - // sign bits for each operand (similar to what we do for binops). - break; + Tmp = std::numeric_limits::max(); + if (!isa(U->getOperand(0))) { + Tmp = ComputeNumSignBits(U->getOperand(0), Depth + 1, Q); + if (Tmp == 1) + break; + } + if (!isa(U->getOperand(1))) { + Tmp = std::min(Tmp, ComputeNumSignBits(U->getOperand(1), Depth + 1, Q)); + if (Tmp == 1) + break; + } + // The input vector(s) provided extra signbit info. + assert(Tmp > 1 && Tmp < std::numeric_limits::max() && + "Unexpected signbits computation for shufflevector"); + return Tmp; } // Finally, if we can prove that the top bits of the result are 0's or 1's, Index: test/Transforms/InstCombine/logical-select.ll =================================================================== --- test/Transforms/InstCombine/logical-select.ll +++ test/Transforms/InstCombine/logical-select.ll @@ -621,11 +621,9 @@ ; CHECK-NEXT: [[SEXT1:%.*]] = sext <4 x i1> [[COND1:%.*]] to <4 x i32> ; CHECK-NEXT: [[SEXT2:%.*]] = sext <4 x i1> [[COND2:%.*]] to <4 x i32> ; CHECK-NEXT: [[COND:%.*]] = shufflevector <4 x i32> [[SEXT1]], <4 x i32> [[SEXT2]], <4 x i32> -; CHECK-NEXT: [[NOTCOND:%.*]] = xor <4 x i32> [[COND]], -; CHECK-NEXT: [[AND1:%.*]] = and <4 x i32> [[NOTCOND]], [[X:%.*]] -; CHECK-NEXT: [[AND2:%.*]] = and <4 x i32> [[COND]], [[Y:%.*]] -; CHECK-NEXT: [[SEL:%.*]] = or <4 x i32> [[AND1]], [[AND2]] -; CHECK-NEXT: ret <4 x i32> [[SEL]] +; CHECK-NEXT: [[TMP1:%.*]] = trunc <4 x i32> [[COND]] to <4 x i1> +; CHECK-NEXT: [[TMP2:%.*]] = select <4 x i1> [[TMP1]], <4 x i32> [[Y:%.*]], <4 x i32> [[X:%.*]] +; CHECK-NEXT: ret <4 x i32> [[TMP2]] ; %sext1 = sext <4 x i1> %cond1 to <4 x i32> %sext2 = sext <4 x i1> %cond2 to <4 x i32>