-
Notifications
You must be signed in to change notification settings - Fork 15.5k
[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
Conversation
|
@llvm/pr-subscribers-llvm-globalisel @llvm/pr-subscribers-backend-aarch64 Author: David Green (davemgreen) ChangesIt 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:
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>)
+...
|
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.
77696aa to
823a8ff
Compare
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.