Skip to content

[GlobalISel] Fix ZExt known bits for scalable vectors. #140213

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 11 additions & 16 deletions llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -481,27 +481,22 @@ void GISelValueTracking::computeKnownBitsImpl(Register R, KnownBits &Known,
break;
// Fall through and handle them the same as zext/trunc.
[[fallthrough]];
case TargetOpcode::G_ASSERT_ZEXT:
case TargetOpcode::G_ZEXT:
case TargetOpcode::G_TRUNC: {
Register SrcReg = MI.getOperand(1).getReg();
LLT SrcTy = MRI.getType(SrcReg);
unsigned SrcBitWidth;

// G_ASSERT_ZEXT stores the original bitwidth in the immediate operand.
if (Opcode == TargetOpcode::G_ASSERT_ZEXT)
SrcBitWidth = MI.getOperand(2).getImm();
else {
SrcBitWidth = SrcTy.isPointer()
? DL.getIndexSizeInBits(SrcTy.getAddressSpace())
: SrcTy.getSizeInBits();
}
assert(SrcBitWidth && "SrcBitWidth can't be zero");
Known = Known.zextOrTrunc(SrcBitWidth);
computeKnownBitsImpl(SrcReg, Known, DemandedElts, Depth + 1);
Known = Known.zextOrTrunc(BitWidth);
if (BitWidth > SrcBitWidth)
Known.Zero.setBitsFrom(SrcBitWidth);
break;
}
case TargetOpcode::G_ASSERT_ZEXT: {
Register SrcReg = MI.getOperand(1).getReg();
computeKnownBitsImpl(SrcReg, Known, DemandedElts, Depth + 1);

unsigned SrcBitWidth = MI.getOperand(2).getImm();
assert(SrcBitWidth && "SrcBitWidth can't be zero");
APInt InMask = APInt::getLowBitsSet(BitWidth, SrcBitWidth);
Known.Zero |= (~InMask);
Known.One &= (~Known.Zero);
break;
}
case TargetOpcode::G_ASSERT_ALIGN: {
Expand Down
67 changes: 67 additions & 0 deletions llvm/test/CodeGen/AArch64/GlobalISel/knownbits-assertzext.mir
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# NOTE: Assertions have been autogenerated by utils/update_givaluetracking_test_checks.py UTC_ARGS: --version 5
# RUN: llc -mtriple aarch64 -mattr=+sve -passes="print<gisel-value-tracking>" %s -filetype=null 2>&1 | FileCheck %s

---
name: ScalarConst
body: |
bb.0:
; CHECK-LABEL: name: @ScalarConst
; CHECK-NEXT: %0:_ KnownBits:00000000000000000000000001111000 SignBits:25
; CHECK-NEXT: %1:_ KnownBits:00000000000000000000000001111000 SignBits:25
%0:_(s32) = G_CONSTANT i32 120
%1:_(s32) = G_ASSERT_ZEXT %0(s32), 16
...
---
name: ScalarVar
body: |
bb.0:
; CHECK-LABEL: name: @ScalarVar
; CHECK-NEXT: %0:_ KnownBits:???????????????????????????????? SignBits:1
; CHECK-NEXT: %1:_ KnownBits:0000000000000000???????????????? SignBits:16
%0:_(s32) = COPY $w0
%1:_(s32) = G_ASSERT_ZEXT %0(s32), 16
...
---
name: VectorCst
body: |
bb.0:
; CHECK-LABEL: name: @VectorCst
; CHECK-NEXT: %0:_ KnownBits:00000000000000000000000001111000 SignBits:25
; CHECK-NEXT: %1:_ KnownBits:00000000000000000000000001111000 SignBits:25
; CHECK-NEXT: %2:_ KnownBits:00000000000000000000000001111000 SignBits:25
%0:_(s32) = G_CONSTANT i32 120
%1:_(<4 x s32>) = G_BUILD_VECTOR %0, %0, %0, %0
%2:_(<4 x s32>) = G_ASSERT_ZEXT %1(<4 x s32>), 16
...
---
name: VectorVar
body: |
bb.0:
; CHECK-LABEL: name: @VectorVar
; CHECK-NEXT: %0:_ KnownBits:???????????????????????????????? SignBits:1
; CHECK-NEXT: %1:_ KnownBits:0000000000000000???????????????? SignBits:16
%0:_(<4 x s32>) = COPY $q0
%1:_(<4 x s32>) = G_ASSERT_ZEXT %0(<4 x s32>), 16
...
---
name: ScalableCst
body: |
bb.0:
; CHECK-LABEL: name: @ScalableCst
; CHECK-NEXT: %0:_ KnownBits:00000000000000000000000001111000 SignBits:25
; CHECK-NEXT: %1:_ KnownBits:00000000000000000000000001111000 SignBits:25
; CHECK-NEXT: %2:_ KnownBits:00000000000000000000000001111000 SignBits:25
%0:_(s32) = G_CONSTANT i32 120
%1:_(<vscale x 4 x s32>) = G_SPLAT_VECTOR %0
%2:_(<vscale x 4 x s32>) = G_ASSERT_ZEXT %1(<vscale x 4 x s32>), 16
...
---
name: ScalableVar
body: |
bb.0:
; CHECK-LABEL: name: @ScalableVar
; CHECK-NEXT: %0:_ KnownBits:???????????????????????????????? SignBits:1
; CHECK-NEXT: %1:_ KnownBits:0000000000000000???????????????? SignBits:16
%0:_(<vscale x 4 x s32>) = COPY $z0
%1:_(<vscale x 4 x s32>) = G_ASSERT_ZEXT %0(<vscale x 4 x s32>), 16
...
67 changes: 67 additions & 0 deletions llvm/test/CodeGen/AArch64/GlobalISel/knownbits-trunk.mir
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# NOTE: Assertions have been autogenerated by utils/update_givaluetracking_test_checks.py UTC_ARGS: --version 5
# RUN: llc -mtriple aarch64 -passes="print<gisel-value-tracking>" %s -filetype=null 2>&1 | FileCheck %s

---
name: ScalarConst
body: |
bb.0:
; CHECK-LABEL: name: @ScalarConst
; CHECK-NEXT: %0:_ KnownBits:10101001100001110110010101000011 SignBits:1
; CHECK-NEXT: %1:_ KnownBits:0110010101000011 SignBits:1
%0:_(s32) = G_CONSTANT i32 2844222787
%1:_(s16) = G_TRUNC %0(s32)
...
---
name: ScalarVar
body: |
bb.0:
; CHECK-LABEL: name: @ScalarVar
; CHECK-NEXT: %0:_ KnownBits:???????????????????????????????? SignBits:1
; CHECK-NEXT: %1:_ KnownBits:???????????????? SignBits:1
%0:_(s32) = COPY $w0
%1:_(s16) = G_TRUNC %0(s32)
...
---
name: VectorCst
body: |
bb.0:
; CHECK-LABEL: name: @VectorCst
; CHECK-NEXT: %0:_ KnownBits:10101001100001110110010101000011 SignBits:1
; CHECK-NEXT: %1:_ KnownBits:10101001100001110110010101000011 SignBits:1
; CHECK-NEXT: %2:_ KnownBits:0110010101000011 SignBits:1
%0:_(s32) = G_CONSTANT i32 2844222787
%1:_(<4 x s32>) = G_BUILD_VECTOR %0, %0, %0, %0
%2:_(<4 x s16>) = G_TRUNC %1(<4 x s32>)
...
---
name: VectorVar
body: |
bb.0:
; CHECK-LABEL: name: @VectorVar
; CHECK-NEXT: %0:_ KnownBits:???????????????????????????????? SignBits:1
; CHECK-NEXT: %1:_ KnownBits:???????????????? SignBits:1
%0:_(<4 x s32>) = COPY $q0
%1:_(<4 x s16>) = G_TRUNC %0(<4 x s32>)
...
---
name: ScalableCst
body: |
bb.0:
; CHECK-LABEL: name: @ScalableCst
; CHECK-NEXT: %0:_ KnownBits:10101001100001110110010101000011 SignBits:1
; CHECK-NEXT: %1:_ KnownBits:10101001100001110110010101000011 SignBits:1
; CHECK-NEXT: %2:_ KnownBits:0110010101000011 SignBits:1
%0:_(s32) = G_CONSTANT i32 2844222787
%1:_(<vscale x 4 x s32>) = G_SPLAT_VECTOR %0
%2:_(<vscale x 4 x s16>) = G_TRUNC %1(<vscale x 4 x s32>)
...
---
name: ScalableVar
body: |
bb.0:
; CHECK-LABEL: name: @ScalableVar
; CHECK-NEXT: %0:_ KnownBits:???????????????????????????????? SignBits:1
; CHECK-NEXT: %1:_ KnownBits:???????????????? SignBits:1
%0:_(<vscale x 4 x s32>) = COPY $z0
%1:_(<vscale x 4 x s16>) = G_TRUNC %0(<vscale x 4 x s32>)
...
67 changes: 67 additions & 0 deletions llvm/test/CodeGen/AArch64/GlobalISel/knownbits-zext.mir
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# NOTE: Assertions have been autogenerated by utils/update_givaluetracking_test_checks.py UTC_ARGS: --version 5
# RUN: llc -mtriple aarch64 -mattr=+sve -passes="print<gisel-value-tracking>" %s -filetype=null 2>&1 | FileCheck %s

---
name: ScalarConst
body: |
bb.0:
; CHECK-LABEL: name: @ScalarConst
; CHECK-NEXT: %0:_ KnownBits:0000000000001010 SignBits:12
; CHECK-NEXT: %1:_ KnownBits:00000000000000000000000000001010 SignBits:28
%0:_(s16) = G_CONSTANT i16 10
%1:_(s32) = G_ZEXT %0(s16)
...
---
name: ScalarVar
body: |
bb.0:
; CHECK-LABEL: name: @ScalarVar
; CHECK-NEXT: %0:_ KnownBits:???????????????? SignBits:1
; CHECK-NEXT: %1:_ KnownBits:0000000000000000???????????????? SignBits:16
%0:_(s16) = COPY $h0
%1:_(s32) = G_ZEXT %0(s16)
...
---
name: VectorCst
body: |
bb.0:
; CHECK-LABEL: name: @VectorCst
; CHECK-NEXT: %0:_ KnownBits:0000000000001010 SignBits:12
; CHECK-NEXT: %1:_ KnownBits:0000000000001010 SignBits:12
; CHECK-NEXT: %2:_ KnownBits:00000000000000000000000000001010 SignBits:28
%0:_(s16) = G_CONSTANT i16 10
%1:_(<4 x s16>) = G_BUILD_VECTOR %0, %0, %0, %0
%2:_(<4 x s32>) = G_ZEXT %1(<4 x s16>)
...
---
name: VectorVar
body: |
bb.0:
; CHECK-LABEL: name: @VectorVar
; CHECK-NEXT: %0:_ KnownBits:???????????????? SignBits:1
; CHECK-NEXT: %1:_ KnownBits:0000000000000000???????????????? SignBits:16
%0:_(<4 x s16>) = COPY $d0
%1:_(<4 x s32>) = G_ZEXT %0(<4 x s16>)
...
---
name: ScalableCst
body: |
bb.0:
; CHECK-LABEL: name: @ScalableCst
; CHECK-NEXT: %0:_ KnownBits:0000000000001010 SignBits:12
; CHECK-NEXT: %1:_ KnownBits:0000000000001010 SignBits:1
; CHECK-NEXT: %2:_ KnownBits:00000000000000000000000000001010 SignBits:28
%0:_(s16) = G_CONSTANT i16 10
%1:_(<vscale x 4 x s16>) = G_SPLAT_VECTOR %0
%2:_(<vscale x 4 x s32>) = G_ZEXT %1(<vscale x 4 x s16>)
...
---
name: ScalableVar
body: |
bb.0:
; CHECK-LABEL: name: @ScalableVar
; CHECK-NEXT: %0:_ KnownBits:???????????????? SignBits:1
; CHECK-NEXT: %1:_ KnownBits:0000000000000000???????????????? SignBits:16
%0:_(<vscale x 4 x s16>) = COPY $z0
%1:_(<vscale x 4 x s32>) = G_ZEXT %0(<vscale x 4 x s16>)
...
Loading