diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -2009,6 +2009,10 @@ if (isa(V)) return OrZero ? match(V, m_Power2OrZero()) : match(V, m_Power2()); + // i1 is by definition a power of 2 or zero. + if (OrZero && V->getType()->getScalarSizeInBits() == 1) + return true; + auto *I = dyn_cast(V); if (!I) return false; diff --git a/llvm/test/Analysis/ValueTracking/known-power-of-two.ll b/llvm/test/Analysis/ValueTracking/known-power-of-two.ll --- a/llvm/test/Analysis/ValueTracking/known-power-of-two.ll +++ b/llvm/test/Analysis/ValueTracking/known-power-of-two.ll @@ -619,8 +619,7 @@ ; CHECK-LABEL: define i16 @i1_is_pow2_or_zero ; CHECK-SAME: (i1 [[X:%.*]], i16 [[Y:%.*]]) { ; CHECK-NEXT: [[XX:%.*]] = zext i1 [[X]] to i16 -; CHECK-NEXT: [[YY:%.*]] = xor i16 [[XX]], [[Y]] -; CHECK-NEXT: [[R:%.*]] = call i16 @llvm.umax.i16(i16 [[YY]], i16 [[Y]]) +; CHECK-NEXT: [[R:%.*]] = or i16 [[XX]], [[Y]] ; CHECK-NEXT: ret i16 [[R]] ; %xx = zext i1 %x to i16 @@ -634,8 +633,7 @@ ; CHECK-SAME: (i1 [[X:%.*]], i16 [[Y0:%.*]], i16 [[Z:%.*]]) { ; CHECK-NEXT: [[XX:%.*]] = zext i1 [[X]] to i16 ; CHECK-NEXT: [[Y:%.*]] = or i16 [[Y0]], [[Z]] -; CHECK-NEXT: [[YY:%.*]] = xor i16 [[Y]], [[XX]] -; CHECK-NEXT: [[R:%.*]] = call i16 @llvm.umax.i16(i16 [[YY]], i16 [[Y]]) +; CHECK-NEXT: [[R:%.*]] = or i16 [[Y]], [[XX]] ; CHECK-NEXT: ret i16 [[R]] ; %xx = zext i1 %x to i16