[InstCombine] fold not-shift of signbit to icmp+zext
https://alive2.llvm.org/ce/z/j_8Wz9
The arithmetic shift was converted to logical shift with:
246078604c
That does not seem to uncover any other missing/conflicting folds,
so convert directly to signbit test + cast.
We still need to fold the pattern with logical shift to test + cast.
This allows reducing patterns where the output type is not
the same as the input value:
https://alive2.llvm.org/ce/z/nydwFV
Fixes #57394
This commit is contained in:
@@ -884,13 +884,13 @@ Instruction *InstCombinerImpl::foldAddWithConstant(BinaryOperator &Add) {
|
||||
if (match(Op0, m_Not(m_Value(X))))
|
||||
return BinaryOperator::CreateSub(InstCombiner::SubOne(Op1C), X);
|
||||
|
||||
// (iN X s>> (N - 1)) + 1 --> (~X) u>> (N - 1)
|
||||
// (iN X s>> (N - 1)) + 1 --> zext (X > -1)
|
||||
const APInt *C;
|
||||
if (match(Op0, m_OneUse(m_AShr(m_Value(X), m_APIntAllowUndef(C)))) &&
|
||||
*C == (Ty->getScalarSizeInBits() - 1) && match(Op1, m_One())) {
|
||||
Value *NotX = Builder.CreateNot(X, X->getName() + ".not");
|
||||
return BinaryOperator::CreateLShr(NotX, ConstantInt::get(Ty, *C));
|
||||
}
|
||||
unsigned BitWidth = Ty->getScalarSizeInBits();
|
||||
if (match(Op0, m_OneUse(m_AShr(m_Value(X),
|
||||
m_SpecificIntAllowUndef(BitWidth - 1)))) &&
|
||||
match(Op1, m_One()))
|
||||
return new ZExtInst(Builder.CreateIsNotNeg(X, "isnotneg"), Ty);
|
||||
|
||||
if (!match(Op1, m_APInt(C)))
|
||||
return nullptr;
|
||||
|
||||
@@ -1900,8 +1900,8 @@ define i8 @not_mul_use2(i8 %x) {
|
||||
|
||||
define i8 @full_ashr_inc(i8 %x) {
|
||||
; CHECK-LABEL: @full_ashr_inc(
|
||||
; CHECK-NEXT: [[X_NOT:%.*]] = xor i8 [[X:%.*]], -1
|
||||
; CHECK-NEXT: [[R:%.*]] = lshr i8 [[X_NOT]], 7
|
||||
; CHECK-NEXT: [[ISNOTNEG:%.*]] = icmp sgt i8 [[X:%.*]], -1
|
||||
; CHECK-NEXT: [[R:%.*]] = zext i1 [[ISNOTNEG]] to i8
|
||||
; CHECK-NEXT: ret i8 [[R]]
|
||||
;
|
||||
%a = ashr i8 %x, 7
|
||||
@@ -1911,8 +1911,8 @@ define i8 @full_ashr_inc(i8 %x) {
|
||||
|
||||
define <2 x i6> @full_ashr_inc_vec(<2 x i6> %x) {
|
||||
; CHECK-LABEL: @full_ashr_inc_vec(
|
||||
; CHECK-NEXT: [[X_NOT:%.*]] = xor <2 x i6> [[X:%.*]], <i6 -1, i6 -1>
|
||||
; CHECK-NEXT: [[R:%.*]] = lshr <2 x i6> [[X_NOT]], <i6 5, i6 5>
|
||||
; CHECK-NEXT: [[ISNOTNEG:%.*]] = icmp sgt <2 x i6> [[X:%.*]], <i6 -1, i6 -1>
|
||||
; CHECK-NEXT: [[R:%.*]] = zext <2 x i1> [[ISNOTNEG]] to <2 x i6>
|
||||
; CHECK-NEXT: ret <2 x i6> [[R]]
|
||||
;
|
||||
%a = ashr <2 x i6> %x, <i6 5, i6 poison>
|
||||
|
||||
@@ -116,8 +116,8 @@ define i64 @n9(i64 %x) {
|
||||
|
||||
define i64 @n10(i64 %x) {
|
||||
; CHECK-LABEL: @n10(
|
||||
; CHECK-NEXT: [[X_NOT:%.*]] = xor i64 [[X:%.*]], -1
|
||||
; CHECK-NEXT: [[R:%.*]] = lshr i64 [[X_NOT]], 63
|
||||
; CHECK-NEXT: [[ISNOTNEG:%.*]] = icmp sgt i64 [[X:%.*]], -1
|
||||
; CHECK-NEXT: [[R:%.*]] = zext i1 [[ISNOTNEG]] to i64
|
||||
; CHECK-NEXT: ret i64 [[R]]
|
||||
;
|
||||
%t0 = lshr i64 %x, 63
|
||||
|
||||
Reference in New Issue
Block a user