diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp index 59486312448e7e..65248eae6acb3d 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -1441,6 +1441,18 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) { break; } + case Intrinsic::bitreverse: { + // bitrev (zext i1 X to ?) --> X ? SignBitC : 0 + Value *X; + if (match(II->getArgOperand(0), m_ZExt(m_Value(X))) && + X->getType()->isIntOrIntVectorTy(1)) { + Type *Ty = II->getType(); + APInt SignBit = APInt::getSignMask(Ty->getScalarSizeInBits()); + return SelectInst::Create(X, ConstantInt::get(Ty, SignBit), + ConstantInt::getNullValue(Ty)); + } + break; + } case Intrinsic::bswap: { Value *IIOperand = II->getArgOperand(0); diff --git a/llvm/test/Transforms/InstCombine/bitreverse.ll b/llvm/test/Transforms/InstCombine/bitreverse.ll index 232d69da9a0257..ab41debc65c77b 100644 --- a/llvm/test/Transforms/InstCombine/bitreverse.ll +++ b/llvm/test/Transforms/InstCombine/bitreverse.ll @@ -323,7 +323,7 @@ define i32 @rev_i1(i1 %x) { ; CHECK-LABEL: @rev_i1( ; CHECK-NEXT: [[Z:%.*]] = zext i1 [[X:%.*]] to i32 ; CHECK-NEXT: call void @use_i32(i32 [[Z]]) -; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[Z]]) +; CHECK-NEXT: [[R:%.*]] = select i1 [[X]], i32 -2147483648, i32 0 ; CHECK-NEXT: ret i32 [[R]] ; %z = zext i1 %x to i32 @@ -334,8 +334,7 @@ define i32 @rev_i1(i1 %x) { define <2 x i8> @rev_v2i1(<2 x i1> %x) { ; CHECK-LABEL: @rev_v2i1( -; CHECK-NEXT: [[Z:%.*]] = zext <2 x i1> [[X:%.*]] to <2 x i8> -; CHECK-NEXT: [[R:%.*]] = call <2 x i8> @llvm.bitreverse.v2i8(<2 x i8> [[Z]]) +; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[X:%.*]], <2 x i8> , <2 x i8> zeroinitializer ; CHECK-NEXT: ret <2 x i8> [[R]] ; %z = zext <2 x i1> %x to <2 x i8> @@ -353,3 +352,19 @@ define i32 @rev_i2(i2 %x) { %r = call i32 @llvm.bitreverse.i32(i32 %z) ret i32 %r } + +; This used to infinite loop. + +define i64 @PR59897(i1 %X1_2) { +; CHECK-LABEL: @PR59897( +; CHECK-NEXT: [[NOT_X1_2:%.*]] = xor i1 [[X1_2:%.*]], true +; CHECK-NEXT: [[X0_3X2X5X0:%.*]] = zext i1 [[NOT_X1_2]] to i64 +; CHECK-NEXT: ret i64 [[X0_3X2X5X0]] +; + %X1_3 = zext i1 %X1_2 to i32 + %X8_3x2x2x0 = call i32 @llvm.bitreverse.i32(i32 %X1_3) + %X8_4x2x3x0 = xor i32 %X8_3x2x2x0, -1 + %X0_3x2x4x0 = lshr i32 %X8_4x2x3x0, 31 + %X0_3x2x5x0 = zext i32 %X0_3x2x4x0 to i64 + ret i64 %X0_3x2x5x0 +}