Index: lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp +++ lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp @@ -470,13 +470,14 @@ // Unsigned shift right. APInt DemandedMaskIn(DemandedMask.shl(ShiftAmt)); + if (SimplifyDemandedBits(I, 0, DemandedMaskIn, Known, Depth + 1)) + return I; + // If the shift is exact, then it does demand the low bits (and knows that - // they are zero). + // they are zero). Do this after we simplify the operand. if (cast(I)->isExact()) DemandedMaskIn.setLowBits(ShiftAmt); - if (SimplifyDemandedBits(I, 0, DemandedMaskIn, Known, Depth + 1)) - return I; assert(!Known.hasConflict() && "Bits known to be one AND zero?"); Known.Zero.lshrInPlace(ShiftAmt); Known.One.lshrInPlace(ShiftAmt); @@ -513,14 +514,14 @@ if (DemandedMask.countLeadingZeros() <= ShiftAmt) DemandedMaskIn.setSignBit(); + if (SimplifyDemandedBits(I, 0, DemandedMaskIn, Known, Depth + 1)) + return I; + // If the shift is exact, then it does demand the low bits (and knows that - // they are zero). + // they are zero). Do this after we simplify the operand. if (cast(I)->isExact()) DemandedMaskIn.setLowBits(ShiftAmt); - if (SimplifyDemandedBits(I, 0, DemandedMaskIn, Known, Depth + 1)) - return I; - unsigned SignBits = ComputeNumSignBits(I->getOperand(0), Depth + 1, CxtI); assert(!Known.hasConflict() && "Bits known to be one AND zero?"); @@ -671,6 +672,19 @@ } computeKnownBits(V, Known, Depth, CxtI); break; + case Instruction::PHI: { + APInt IKnownZero = APInt::getAllOnesValue(BitWidth); + APInt IKnownOne = APInt::getAllOnesValue(BitWidth); + for (unsigned i = 0; i != cast(I)->getNumIncomingValues(); ++i) { + KnownBits PhiOperandKnown(BitWidth); + SimplifyDemandedBits(I, i, DemandedMask, PhiOperandKnown, Depth + 1); + IKnownZero = IKnownZero & PhiOperandKnown.Zero; + IKnownOne = IKnownOne & PhiOperandKnown.One; + } + Known.Zero = std::move(IKnownZero); + Known.One = std::move(IKnownOne); + break; + } } // If the client is only demanding bits that we know, return the known Index: test/Transforms/InstCombine/simplify-demanded-bits-across-phi.ll =================================================================== --- test/Transforms/InstCombine/simplify-demanded-bits-across-phi.ll +++ test/Transforms/InstCombine/simplify-demanded-bits-across-phi.ll @@ -0,0 +1,43 @@ +; RUN: opt -S -instcombine < %s | FileCheck %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-grtev4-linux-gnu" + +@bar = local_unnamed_addr global i32 0, align 4 + +define void @foo(i64, i32) { + switch i32 %1, label %10 [ + i32 1, label %3 + i32 2, label %6 + ] + +;