diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp index 67d1845832725..480f319801392 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -3846,6 +3846,8 @@ static Instruction *foldBitCeil(SelectInst &SI, IRBuilderBase &Builder, InstCombinerImpl &IC) { Type *SelType = SI.getType(); unsigned BitWidth = SelType->getScalarSizeInBits(); + if (!isPowerOf2_32(BitWidth)) + return nullptr; Value *FalseVal = SI.getFalseValue(); Value *TrueVal = SI.getTrueValue(); diff --git a/llvm/test/Transforms/InstCombine/bit_ceil.ll b/llvm/test/Transforms/InstCombine/bit_ceil.ll index 09f90ee05735d..edf1c176ff12c 100644 --- a/llvm/test/Transforms/InstCombine/bit_ceil.ll +++ b/llvm/test/Transforms/InstCombine/bit_ceil.ll @@ -337,6 +337,25 @@ define i32 @test_drop_range_attr(i32 %x) { ret i32 %sel } +define i33 @test_bit_ceil_i33_non_pow2(i33 %x) { +; CHECK-LABEL: @test_bit_ceil_i33_non_pow2( +; CHECK-NEXT: [[CTLZ:%.*]] = call range(i33 0, 34) i33 @llvm.ctlz.i33(i33 [[X:%.*]], i1 false) +; CHECK-NEXT: [[TMP2:%.*]] = sub nuw nsw i33 33, [[CTLZ]] +; CHECK-NEXT: [[SEL:%.*]] = shl nuw i33 1, [[TMP2]] +; CHECK-NEXT: [[DEC:%.*]] = add i33 [[X]], -1 +; CHECK-NEXT: [[ULT:%.*]] = icmp ult i33 [[DEC]], -2 +; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[ULT]], i33 [[SEL]], i33 1 +; CHECK-NEXT: ret i33 [[SEL1]] +; + %ctlz = call i33 @llvm.ctlz.i33(i33 %x, i1 false) + %sub = sub i33 33, %ctlz + %shl = shl i33 1, %sub + %dec = add i33 %x, -1 + %ult = icmp ult i33 %dec, -2 + %sel = select i1 %ult, i33 %shl, i33 1 + ret i33 %sel +} + define i32 @bit_ceil_plus_nsw(i32 %x) { ; CHECK-LABEL: @bit_ceil_plus_nsw( ; CHECK-NEXT: entry: @@ -378,5 +397,6 @@ entry: } declare i32 @llvm.ctlz.i32(i32, i1 immarg) +declare i33 @llvm.ctlz.i33(i33, i1 immarg) declare i64 @llvm.ctlz.i64(i64, i1 immarg) declare <4 x i32> @llvm.ctlz.v4i32(<4 x i32>, i1)