Skip to content

Commit 6e6fe27

Browse files
committed
[ValueTracking] peek through extends in haveNoCommonBitsSet (2nd try)
The 1st try was not clean because a portion of the code diff made it into the pre-commit patch to add tests. This should be the same end result without the muddied code diff. Original commit message: In cases with matching extends, this allows changing an 'add' into an 'or' and narrowing the 'or' which then simplifies to a constant. In cases with opposite extends, we just convert to an 'or' currently, but that could be reduced too. https://alive2.llvm.org/ce/z/fTHzdb
1 parent 2e5a0b3 commit 6e6fe27

File tree

2 files changed

+17
-23
lines changed

2 files changed

+17
-23
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,15 @@ bool llvm::haveNoCommonBitsSet(const Value *LHS, const Value *RHS,
270270
match(LHS, m_c_Xor(m_c_And(m_Specific(RHS), m_Value(Y)), m_Deferred(Y))))
271271
return true;
272272

273+
// Peek through extends to find a 'not' of the other side:
274+
// (ext Y) op ext(~Y)
275+
// (ext ~Y) op ext(Y)
276+
if ((match(LHS, m_ZExtOrSExt(m_Value(Y))) &&
277+
match(RHS, m_ZExtOrSExt(m_Not(m_Specific(Y))))) ||
278+
(match(RHS, m_ZExtOrSExt(m_Value(Y))) &&
279+
match(LHS, m_ZExtOrSExt(m_Not(m_Specific(Y))))))
280+
return true;
281+
273282
// Look for: (A & B) op ~(A | B)
274283
{
275284
Value *A, *B;

llvm/test/Transforms/InstCombine/add.ll

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2348,11 +2348,7 @@ define <vscale x 1 x i32> @add_to_or_scalable(<vscale x 1 x i32> %in) {
23482348

23492349
define i5 @zext_zext_not(i3 %x) {
23502350
; CHECK-LABEL: @zext_zext_not(
2351-
; CHECK-NEXT: [[ZX:%.*]] = zext i3 [[X:%.*]] to i5
2352-
; CHECK-NEXT: [[NOTX:%.*]] = xor i3 [[X]], -1
2353-
; CHECK-NEXT: [[ZNOTX:%.*]] = zext i3 [[NOTX]] to i5
2354-
; CHECK-NEXT: [[R:%.*]] = add nuw nsw i5 [[ZX]], [[ZNOTX]]
2355-
; CHECK-NEXT: ret i5 [[R]]
2351+
; CHECK-NEXT: ret i5 7
23562352
;
23572353
%zx = zext i3 %x to i5
23582354
%notx = xor i3 %x, -1
@@ -2363,11 +2359,7 @@ define i5 @zext_zext_not(i3 %x) {
23632359

23642360
define <2 x i5> @zext_zext_not_commute(<2 x i3> %x) {
23652361
; CHECK-LABEL: @zext_zext_not_commute(
2366-
; CHECK-NEXT: [[ZX:%.*]] = zext <2 x i3> [[X:%.*]] to <2 x i5>
2367-
; CHECK-NEXT: [[NOTX:%.*]] = xor <2 x i3> [[X]], <i3 -1, i3 poison>
2368-
; CHECK-NEXT: [[ZNOTX:%.*]] = zext <2 x i3> [[NOTX]] to <2 x i5>
2369-
; CHECK-NEXT: [[R:%.*]] = add nuw nsw <2 x i5> [[ZNOTX]], [[ZX]]
2370-
; CHECK-NEXT: ret <2 x i5> [[R]]
2362+
; CHECK-NEXT: ret <2 x i5> <i5 7, i5 7>
23712363
;
23722364
%zx = zext <2 x i3> %x to <2 x i5>
23732365
%notx = xor <2 x i3> %x, <i3 -1, i3 poison>
@@ -2378,11 +2370,7 @@ define <2 x i5> @zext_zext_not_commute(<2 x i3> %x) {
23782370

23792371
define i9 @sext_sext_not(i3 %x) {
23802372
; CHECK-LABEL: @sext_sext_not(
2381-
; CHECK-NEXT: [[SX:%.*]] = sext i3 [[X:%.*]] to i9
2382-
; CHECK-NEXT: [[NOTX:%.*]] = xor i3 [[X]], -1
2383-
; CHECK-NEXT: [[SNOTX:%.*]] = sext i3 [[NOTX]] to i9
2384-
; CHECK-NEXT: [[R:%.*]] = add nsw i9 [[SX]], [[SNOTX]]
2385-
; CHECK-NEXT: ret i9 [[R]]
2373+
; CHECK-NEXT: ret i9 -1
23862374
;
23872375
%sx = sext i3 %x to i9
23882376
%notx = xor i3 %x, -1
@@ -2395,10 +2383,7 @@ define i8 @sext_sext_not_commute(i3 %x) {
23952383
; CHECK-LABEL: @sext_sext_not_commute(
23962384
; CHECK-NEXT: [[SX:%.*]] = sext i3 [[X:%.*]] to i8
23972385
; CHECK-NEXT: call void @use(i8 [[SX]])
2398-
; CHECK-NEXT: [[NOTX:%.*]] = xor i3 [[X]], -1
2399-
; CHECK-NEXT: [[SNOTX:%.*]] = sext i3 [[NOTX]] to i8
2400-
; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[SNOTX]], [[SX]]
2401-
; CHECK-NEXT: ret i8 [[R]]
2386+
; CHECK-NEXT: ret i8 -1
24022387
;
24032388

24042389
%sx = sext i3 %x to i8
@@ -2414,7 +2399,7 @@ define i5 @zext_sext_not(i4 %x) {
24142399
; CHECK-NEXT: [[ZX:%.*]] = zext i4 [[X:%.*]] to i5
24152400
; CHECK-NEXT: [[NOTX:%.*]] = xor i4 [[X]], -1
24162401
; CHECK-NEXT: [[SNOTX:%.*]] = sext i4 [[NOTX]] to i5
2417-
; CHECK-NEXT: [[R:%.*]] = add i5 [[ZX]], [[SNOTX]]
2402+
; CHECK-NEXT: [[R:%.*]] = or i5 [[ZX]], [[SNOTX]]
24182403
; CHECK-NEXT: ret i5 [[R]]
24192404
;
24202405
%zx = zext i4 %x to i5
@@ -2431,7 +2416,7 @@ define i8 @zext_sext_not_commute(i4 %x) {
24312416
; CHECK-NEXT: [[NOTX:%.*]] = xor i4 [[X]], -1
24322417
; CHECK-NEXT: [[SNOTX:%.*]] = sext i4 [[NOTX]] to i8
24332418
; CHECK-NEXT: call void @use(i8 [[SNOTX]])
2434-
; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[SNOTX]], [[ZX]]
2419+
; CHECK-NEXT: [[R:%.*]] = or i8 [[SNOTX]], [[ZX]]
24352420
; CHECK-NEXT: ret i8 [[R]]
24362421
;
24372422
%zx = zext i4 %x to i8
@@ -2448,7 +2433,7 @@ define i9 @sext_zext_not(i4 %x) {
24482433
; CHECK-NEXT: [[SX:%.*]] = sext i4 [[X:%.*]] to i9
24492434
; CHECK-NEXT: [[NOTX:%.*]] = xor i4 [[X]], -1
24502435
; CHECK-NEXT: [[ZNOTX:%.*]] = zext i4 [[NOTX]] to i9
2451-
; CHECK-NEXT: [[R:%.*]] = add nsw i9 [[SX]], [[ZNOTX]]
2436+
; CHECK-NEXT: [[R:%.*]] = or i9 [[SX]], [[ZNOTX]]
24522437
; CHECK-NEXT: ret i9 [[R]]
24532438
;
24542439
%sx = sext i4 %x to i9
@@ -2463,7 +2448,7 @@ define i9 @sext_zext_not_commute(i4 %x) {
24632448
; CHECK-NEXT: [[SX:%.*]] = sext i4 [[X:%.*]] to i9
24642449
; CHECK-NEXT: [[NOTX:%.*]] = xor i4 [[X]], -1
24652450
; CHECK-NEXT: [[ZNOTX:%.*]] = zext i4 [[NOTX]] to i9
2466-
; CHECK-NEXT: [[R:%.*]] = add nsw i9 [[ZNOTX]], [[SX]]
2451+
; CHECK-NEXT: [[R:%.*]] = or i9 [[ZNOTX]], [[SX]]
24672452
; CHECK-NEXT: ret i9 [[R]]
24682453
;
24692454
%sx = sext i4 %x to i9

0 commit comments

Comments
 (0)