Index: llvm/include/llvm/IR/PatternMatch.h =================================================================== --- llvm/include/llvm/IR/PatternMatch.h +++ llvm/include/llvm/IR/PatternMatch.h @@ -1735,10 +1735,10 @@ return false; // At this point we have a select conditioned on a comparison. Check that // it is the values returned by the select that are being compared. - Value *TrueVal = SI->getTrueValue(); - Value *FalseVal = SI->getFalseValue(); - Value *LHS = Cmp->getOperand(0); - Value *RHS = Cmp->getOperand(1); + auto *TrueVal = SI->getTrueValue(); + auto *FalseVal = SI->getFalseValue(); + auto *LHS = Cmp->getOperand(0); + auto *RHS = Cmp->getOperand(1); if ((TrueVal != LHS || FalseVal != RHS) && (TrueVal != RHS || FalseVal != LHS)) return false; Index: llvm/lib/Analysis/ValueTracking.cpp =================================================================== --- llvm/lib/Analysis/ValueTracking.cpp +++ llvm/lib/Analysis/ValueTracking.cpp @@ -1977,6 +1977,12 @@ return isKnownToBeAPowerOfTwo(SI->getTrueValue(), OrZero, Depth, Q) && isKnownToBeAPowerOfTwo(SI->getFalseValue(), OrZero, Depth, Q); + // Peek through min/max. + if (match(V, m_MaxOrMin(m_Value(X), m_Value(Y)))) { + return isKnownToBeAPowerOfTwo(X, OrZero, Depth, Q) && + isKnownToBeAPowerOfTwo(Y, OrZero, Depth, Q); + } + if (OrZero && match(V, m_And(m_Value(X), m_Value(Y)))) { // A power of two and'd with anything is a power of two or zero. if (isKnownToBeAPowerOfTwo(X, /*OrZero*/ true, Depth, Q) || Index: llvm/test/Transforms/InstSimplify/AndOrXor.ll =================================================================== --- llvm/test/Transforms/InstSimplify/AndOrXor.ll +++ llvm/test/Transforms/InstSimplify/AndOrXor.ll @@ -97,9 +97,7 @@ ; CHECK-NEXT: [[SHX:%.*]] = shl i32 2, [[X:%.*]] ; CHECK-NEXT: [[SHY:%.*]] = shl i32 32, [[Y:%.*]] ; CHECK-NEXT: [[M:%.*]] = call i32 @llvm.smax.i32(i32 [[SHX]], i32 [[SHY]]) -; CHECK-NEXT: [[NEG:%.*]] = sub i32 0, [[M]] -; CHECK-NEXT: [[R:%.*]] = and i32 [[M]], [[NEG]] -; CHECK-NEXT: ret i32 [[R]] +; CHECK-NEXT: ret i32 [[M]] ; %shx = shl i32 2, %x %shy = shl i32 32, %y @@ -133,12 +131,7 @@ define <2 x i32> @pow2_decrement_min_vec(<2 x i32> %x, <2 x i32> %y) { ; CHECK-LABEL: @pow2_decrement_min_vec( -; CHECK-NEXT: [[P1:%.*]] = and <2 x i32> [[X:%.*]], -; CHECK-NEXT: [[P2:%.*]] = shl <2 x i32> , [[Y:%.*]] -; CHECK-NEXT: [[M:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[P1]], <2 x i32> [[P2]]) -; CHECK-NEXT: [[A:%.*]] = add <2 x i32> [[M]], -; CHECK-NEXT: [[R:%.*]] = and <2 x i32> [[M]], [[A]] -; CHECK-NEXT: ret <2 x i32> [[R]] +; CHECK-NEXT: ret <2 x i32> zeroinitializer ; %p1 = and <2 x i32> %x, %p2 = shl <2 x i32> , %y