Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

[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

Open
wants to merge 1 commit into
base: main
Choose a base branch
Loading
from

Conversation

davemgreen
Copy link
Collaborator

It was using the full size of the vector as the SrcBitWidth. This patch changes the code to split G_ASSERT_ZEXT away from the others (G_INTTOPTR / G_PTRTOINT / G_ZEXT / G_TRUNC) which are simpler, and make the code match the SDAG equivalent.

It was using the full size of the vector as the SrcBitWidth. This patch changes
the code to split G_ASSERT_ZEXT away from the others (G_INTTOPTR / G_PTRTOINT /
G_ZEXT / G_TRUNC) which are simpler, and make the code match the SDAG
equivalent.
@llvmbot
Copy link
Member

llvmbot commented May 16, 2025

@llvm/pr-subscribers-llvm-globalisel

@llvm/pr-subscribers-backend-aarch64

Author: David Green (davemgreen)

Changes

It was using the full size of the vector as the SrcBitWidth. This patch changes the code to split G_ASSERT_ZEXT away from the others (G_INTTOPTR / G_PTRTOINT / G_ZEXT / G_TRUNC) which are simpler, and make the code match the SDAG equivalent.


Full diff: https://github.com/llvm/llvm-project/pull/140213.diff

4 Files Affected:

  • (modified) llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp (+11-16)
  • (added) llvm/test/CodeGen/AArch64/GlobalISel/knownbits-assertzext.mir (+67)
  • (added) llvm/test/CodeGen/AArch64/GlobalISel/knownbits-trunk.mir (+67)
  • (added) llvm/test/CodeGen/AArch64/GlobalISel/knownbits-zext.mir (+67)
diff --git a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
index 589936b6c260f..e7cd91cc93d3f 100644
--- a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
@@ -472,27 +472,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: {
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-assertzext.mir b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-assertzext.mir
new file mode 100644
index 0000000000000..ab363618afc98
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-assertzext.mir
@@ -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 -o - 2>&1 | FileCheck %s
+
+---
+name:            ScalarConst
+body:             |
+  bb.0:
+  ; CHECK-LABEL: name: @ScalarConst
+  ; CHECK-NEXT: %0:_ KnownBits:10101001100001110110010101000011 SignBits:1
+  ; CHECK-NEXT: %1:_ KnownBits:00000000000000000110010101000011 SignBits:17
+    %0:_(s32) = G_CONSTANT i32 2844222787
+    %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:10101001100001110110010101000011 SignBits:1
+  ; CHECK-NEXT: %1:_ KnownBits:10101001100001110110010101000011 SignBits:1
+  ; CHECK-NEXT: %2:_ KnownBits:00000000000000000110010101000011 SignBits:17
+    %0:_(s32) = G_CONSTANT i32 2844222787
+    %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:10101001100001110110010101000011 SignBits:1
+  ; CHECK-NEXT: %1:_ KnownBits:???????????????????????????????? SignBits:1
+  ; CHECK-NEXT: %2:_ KnownBits:0000000000000000???????????????? SignBits:16
+    %0:_(s32) = G_CONSTANT i32 2844222787
+    %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
+...
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-trunk.mir b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-trunk.mir
new file mode 100644
index 0000000000000..23f1a98c91c0f
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-trunk.mir
@@ -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 -o - 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:???????????????????????????????? SignBits:1
+  ; CHECK-NEXT: %2:_ KnownBits:???????????????? 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>)
+...
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-zext.mir b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-zext.mir
new file mode 100644
index 0000000000000..9275d2990bbe3
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-zext.mir
@@ -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 -o - 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:???????????????? SignBits:1
+  ; CHECK-NEXT: %2:_ KnownBits:0000000000000000???????????????? SignBits:16
+    %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>)
+...

@@ -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 -o - 2>&1 | FileCheck %s
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# RUN: llc -mtriple aarch64 -mattr=+sve -passes="print<gisel-value-tracking>" %s -o - 2>&1 | FileCheck %s
# RUN: llc -mtriple aarch64 -mattr=+sve -passes="print<gisel-value-tracking>" -filetype=null %s 2>&1 | FileCheck %s

Don't emit unused stdout

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks - I wanted something like --disable-output but hadn't realized filetype could be null.

@@ -0,0 +1,67 @@
# NOTE: Assertions have been autogenerated by utils/update_givaluetracking_test_checks.py UTC_ARGS: --version 5
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was this committed already? I don't see it

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, It is on it's way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants
Morty Proxy This is a proxified and sanitized view of the page, visit original site.