Skip to content

Commit 6c39a3a

Browse files
committed
[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: 2460786 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
1 parent b345be1 commit 6c39a3a

File tree

3 files changed

+12
-12
lines changed

3 files changed

+12
-12
lines changed

llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -884,13 +884,13 @@ Instruction *InstCombinerImpl::foldAddWithConstant(BinaryOperator &Add) {
884884
if (match(Op0, m_Not(m_Value(X))))
885885
return BinaryOperator::CreateSub(InstCombiner::SubOne(Op1C), X);
886886

887-
// (iN X s>> (N - 1)) + 1 --> (~X) u>> (N - 1)
887+
// (iN X s>> (N - 1)) + 1 --> zext (X > -1)
888888
const APInt *C;
889-
if (match(Op0, m_OneUse(m_AShr(m_Value(X), m_APIntAllowUndef(C)))) &&
890-
*C == (Ty->getScalarSizeInBits() - 1) && match(Op1, m_One())) {
891-
Value *NotX = Builder.CreateNot(X, X->getName() + ".not");
892-
return BinaryOperator::CreateLShr(NotX, ConstantInt::get(Ty, *C));
893-
}
889+
unsigned BitWidth = Ty->getScalarSizeInBits();
890+
if (match(Op0, m_OneUse(m_AShr(m_Value(X),
891+
m_SpecificIntAllowUndef(BitWidth - 1)))) &&
892+
match(Op1, m_One()))
893+
return new ZExtInst(Builder.CreateIsNotNeg(X, "isnotneg"), Ty);
894894

895895
if (!match(Op1, m_APInt(C)))
896896
return nullptr;

llvm/test/Transforms/InstCombine/add.ll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1900,8 +1900,8 @@ define i8 @not_mul_use2(i8 %x) {
19001900

19011901
define i8 @full_ashr_inc(i8 %x) {
19021902
; CHECK-LABEL: @full_ashr_inc(
1903-
; CHECK-NEXT: [[X_NOT:%.*]] = xor i8 [[X:%.*]], -1
1904-
; CHECK-NEXT: [[R:%.*]] = lshr i8 [[X_NOT]], 7
1903+
; CHECK-NEXT: [[ISNOTNEG:%.*]] = icmp sgt i8 [[X:%.*]], -1
1904+
; CHECK-NEXT: [[R:%.*]] = zext i1 [[ISNOTNEG]] to i8
19051905
; CHECK-NEXT: ret i8 [[R]]
19061906
;
19071907
%a = ashr i8 %x, 7
@@ -1911,8 +1911,8 @@ define i8 @full_ashr_inc(i8 %x) {
19111911

19121912
define <2 x i6> @full_ashr_inc_vec(<2 x i6> %x) {
19131913
; CHECK-LABEL: @full_ashr_inc_vec(
1914-
; CHECK-NEXT: [[X_NOT:%.*]] = xor <2 x i6> [[X:%.*]], <i6 -1, i6 -1>
1915-
; CHECK-NEXT: [[R:%.*]] = lshr <2 x i6> [[X_NOT]], <i6 5, i6 5>
1914+
; CHECK-NEXT: [[ISNOTNEG:%.*]] = icmp sgt <2 x i6> [[X:%.*]], <i6 -1, i6 -1>
1915+
; CHECK-NEXT: [[R:%.*]] = zext <2 x i1> [[ISNOTNEG]] to <2 x i6>
19161916
; CHECK-NEXT: ret <2 x i6> [[R]]
19171917
;
19181918
%a = ashr <2 x i6> %x, <i6 5, i6 poison>

llvm/test/Transforms/InstCombine/high-bit-signmask.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,8 @@ define i64 @n9(i64 %x) {
116116

117117
define i64 @n10(i64 %x) {
118118
; CHECK-LABEL: @n10(
119-
; CHECK-NEXT: [[X_NOT:%.*]] = xor i64 [[X:%.*]], -1
120-
; CHECK-NEXT: [[R:%.*]] = lshr i64 [[X_NOT]], 63
119+
; CHECK-NEXT: [[ISNOTNEG:%.*]] = icmp sgt i64 [[X:%.*]], -1
120+
; CHECK-NEXT: [[R:%.*]] = zext i1 [[ISNOTNEG]] to i64
121121
; CHECK-NEXT: ret i64 [[R]]
122122
;
123123
%t0 = lshr i64 %x, 63

0 commit comments

Comments
 (0)