[llvm] [GlobalISel] Fold instructions with fully-known bits to a constant. (PR #224254)
Vikash Gupta via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 17 05:09:34 PDT 2026
https://github.com/vg0204 updated https://github.com/llvm/llvm-project/pull/224254
>From 9ea569fe1d6a6eea3325682210805dac2e10a69b Mon Sep 17 00:00:00 2001
From: vg0204 <Vikash.Gupta at amd.com>
Date: Thu, 17 Sep 2026 14:38:31 +0530
Subject: [PATCH] [GlobalISel] Fold instructions with fully-known bits to a
constant
Port SelectionDAG's `SimplifyDemandedBits` "all demanded bits known ->
constant" shortcut to GlobalISel: when value tracking proves every bit
of a def is known, replacing the instruction with the materialized constant.
It adds a `known_bits_to_constant` combine (rooted on `G_AND`, `G_OR`,
`G_ZEXT`, `G_SEXT`, `G_TRUNC`) to the `known_bits_simplifications` group.
Unlike the `constant_fold_*` rules, this fires when the result is fully
known even though the operands are only partially known.
---
.../llvm/CodeGen/GlobalISel/CombinerHelper.h | 5 +
.../include/llvm/Target/GlobalISel/Combine.td | 9 +
.../lib/CodeGen/GlobalISel/CombinerHelper.cpp | 29 +++
.../combine-known-bits-to-constant.ll | 35 +++
.../combine-known-bits-to-constant.mir | 202 ++++++++++++++++++
.../GlobalISel/combine-logic-of-compare.mir | 5 +-
.../AArch64/GlobalISel/combine-overflow.mir | 5 +-
.../AArch64/GlobalISel/combine-trunc.mir | 22 +-
.../legalize-shuffle-vector-widen-crash.ll | 21 +-
llvm/test/CodeGen/AArch64/arm64-vshift.ll | 3 +-
llvm/test/CodeGen/AArch64/hadd-combine.ll | 56 ++---
.../AArch64/neon-compare-instructions.ll | 35 +--
.../GlobalISel/combine-redundant-and.mir | 5 +-
...mbine-shl-from-extend-narrow.postlegal.mir | 8 +-
...ombine-shl-from-extend-narrow.prelegal.mir | 12 +-
.../combine-short-clamp-inverted-bounds.mir | 8 +-
.../llvm.amdgcn.make.buffer.rsrc.ll | 78 +++----
.../CodeGen/RISCV/GlobalISel/rotl-rotr.ll | 23 +-
18 files changed, 398 insertions(+), 163 deletions(-)
create mode 100644 llvm/test/CodeGen/AArch64/GlobalISel/combine-known-bits-to-constant.ll
create mode 100644 llvm/test/CodeGen/AArch64/GlobalISel/combine-known-bits-to-constant.mir
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
index 9f020ba7be528..2059a92f59594 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
@@ -574,6 +574,11 @@ class CombinerHelper {
LLVM_ABI bool matchRedundantAnd(MachineInstr &MI,
Register &Replacement) const;
+ /// \return true if all bits of \p MI's result are known, storing that
+ /// constant in \p MatchInfo so \p MI can be replaced by that constant.
+ LLVM_ABI bool matchKnownBitsToConstant(MachineInstr &MI,
+ APInt &MatchInfo) const;
+
/// \return true if \p MI is a G_OR instruction whose operands are x and y
/// where x | y == x or x | y == y. (E.g., one of operands is all-zeros
/// value.)
diff --git a/llvm/include/llvm/Target/GlobalISel/Combine.td b/llvm/include/llvm/Target/GlobalISel/Combine.td
index 3735e95ee8f68..0c7d8681f17f7 100644
--- a/llvm/include/llvm/Target/GlobalISel/Combine.td
+++ b/llvm/include/llvm/Target/GlobalISel/Combine.td
@@ -1005,6 +1005,14 @@ def overlapping_and: GICombineRule <
(apply [{ Helper.applyBuildFn(*${root}, ${info}); }])
>;
+// Fold a fully-known result to its constant (SelectionDAG's SimplifyDemandedBits
+// "all bits known -> constant" shortcut).
+def known_bits_to_constant : GICombineRule<
+ (defs root:$root, apint_matchinfo:$matchinfo),
+ (match (wip_match_opcode G_AND, G_OR, G_ZEXT, G_SEXT, G_TRUNC):$root,
+ [{ return Helper.matchKnownBitsToConstant(*${root}, ${matchinfo}); }]),
+ (apply [{ Helper.replaceInstWithConstant(*${root}, ${matchinfo}); }])>;
+
// Fold (x & y) -> x or (x & y) -> y when (x & y) is known to equal x or equal y.
def redundant_and: GICombineRule <
(defs root:$root, register_matchinfo:$matchinfo),
@@ -2775,6 +2783,7 @@ def const_combines : GICombineGroup<[constant_fold_fp_ops, const_ptradd_to_i2p,
combine_minmax_nan, expand_const_fpowi]>;
def known_bits_simplifications : GICombineGroup<[
+ known_bits_to_constant,
redundant_sext_inreg, redundant_zext_sext_inreg, redundant_aext_sext_inreg,
redundant_zext_unmerge_sext_inreg, redundant_aext_unmerge_sext_inreg,
redundant_and, redundant_or, urem_pow2_to_mask, zext_trunc_fold,
diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
index 4dce66a74cacc..413fabbff0c33 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -3363,6 +3363,35 @@ bool CombinerHelper::matchRedundantAnd(MachineInstr &MI,
return false;
}
+bool CombinerHelper::matchKnownBitsToConstant(MachineInstr &MI,
+ APInt &MatchInfo) const {
+ if (!VT)
+ return false;
+
+ Register Dst = MI.getOperand(0).getReg();
+ LLT Ty = MRI.getType(Dst);
+
+ // Scalars and fixed vectors. getKnownBits intersects all lanes, so a constant
+ // vector result is necessarily a splat-constant.
+ if (!Ty.isScalar() && !Ty.isFixedVector())
+ return false;
+
+ // Don't materialize a def that already has a class/bank constraint into a
+ // constant.
+ if (!MRI.getRegClassOrRegBank(Dst).isNull())
+ return false;
+
+ if (!isConstantLegalOrBeforeLegalizer(Ty))
+ return false;
+
+ KnownBits Known = VT->getKnownBits(Dst);
+ if (!Known.isConstant())
+ return false;
+
+ MatchInfo = Known.getConstant();
+ return true;
+}
+
bool CombinerHelper::matchRedundantOr(MachineInstr &MI,
Register &Replacement) const {
// Given
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-known-bits-to-constant.ll b/llvm/test/CodeGen/AArch64/GlobalISel/combine-known-bits-to-constant.ll
new file mode 100644
index 0000000000000..cd0c6f1e99d83
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-known-bits-to-constant.ll
@@ -0,0 +1,35 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=aarch64 -global-isel -global-isel-abort=1 -O1 %s -o - | FileCheck %s
+
+; lshr -> top byte only; the AND masks it away, so the result is known 0.
+define i32 @and_masks_to_zero(i32 %x) {
+; CHECK-LABEL: and_masks_to_zero:
+; CHECK: // %bb.0:
+; CHECK-NEXT: mov w0, wzr
+; CHECK-NEXT: ret
+ %s = lshr i32 %x, 24
+ %a = and i32 %s, 4294967040
+ ret i32 %a
+}
+
+; Each OR pins a disjoint half of the bits to 1, so every bit is known 1 -> -1.
+define i32 @or_pins_all_bits(i32 %x, i32 %y) {
+; CHECK-LABEL: or_pins_all_bits:
+; CHECK: // %bb.0:
+; CHECK-NEXT: mov w0, #-1 // =0xffffffff
+; CHECK-NEXT: ret
+ %a = or i32 %x, 15
+ %b = or i32 %y, 4294967280
+ %o = or i32 %a, %b
+ ret i32 %o
+}
+
+; Negative: low byte unknown, so nothing is folded.
+define i32 @not_fully_known(i32 %x) {
+; CHECK-LABEL: not_fully_known:
+; CHECK: // %bb.0:
+; CHECK-NEXT: and w0, w0, #0xff
+; CHECK-NEXT: ret
+ %a = and i32 %x, 255
+ ret i32 %a
+}
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-known-bits-to-constant.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-known-bits-to-constant.mir
new file mode 100644
index 0000000000000..eb2e18392135b
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-known-bits-to-constant.mir
@@ -0,0 +1,202 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -run-pass=aarch64-prelegalizer-combiner -mtriple aarch64-unknown-unknown %s -o - | FileCheck %s
+
+# known_bits_to_constant folds a fully-known result to a constant even when it is
+# built from partially-known operands, so the result equals neither operand and
+# redundant_and/redundant_or cannot fire.
+
+---
+# lshr by 24 -> bits 8..31 known 0; anding with 0xFFFFFF00 clears the low 8 -> 0.
+name: and_of_lshr_to_zero
+body: |
+ bb.0:
+ liveins: $w0
+ ; CHECK-LABEL: name: and_of_lshr_to_zero
+ ; CHECK: liveins: $w0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: $w0 = COPY [[C]](s32)
+ %0:_(s32) = COPY $w0
+ %1:_(s32) = G_CONSTANT i32 24
+ %2:_(s32) = G_LSHR %0, %1
+ %3:_(s32) = G_CONSTANT i32 -256
+ %4:_(s32) = G_AND %2, %3
+ $w0 = COPY %4(s32)
+...
+---
+# Each or pins a disjoint half of the bits to 1, so every bit is known 1 -> -1.
+name: or_partial_to_allones
+body: |
+ bb.0:
+ liveins: $w0, $w1
+ ; CHECK-LABEL: name: or_partial_to_allones
+ ; CHECK: liveins: $w0, $w1
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
+ ; CHECK-NEXT: $w0 = COPY [[C]](s32)
+ %0:_(s32) = COPY $w0
+ %1:_(s32) = COPY $w1
+ %2:_(s32) = G_CONSTANT i32 15
+ %3:_(s32) = G_OR %0, %2
+ %4:_(s32) = G_CONSTANT i32 -16
+ %5:_(s32) = G_OR %1, %4
+ %6:_(s32) = G_OR %3, %5
+ $w0 = COPY %6(s32)
+...
+---
+# Vector: every lane is fully known, so getKnownBits proves a splat -> splat 0.
+name: vec_and_of_lshr_to_zero
+body: |
+ bb.0:
+ liveins: $q0
+ ; CHECK-LABEL: name: vec_and_of_lshr_to_zero
+ ; CHECK: liveins: $q0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[C]](s32), [[C]](s32), [[C]](s32), [[C]](s32)
+ ; CHECK-NEXT: $q0 = COPY [[BUILD_VECTOR]](<4 x s32>)
+ %0:_(<4 x s32>) = COPY $q0
+ %1:_(s32) = G_CONSTANT i32 24
+ %2:_(<4 x s32>) = G_BUILD_VECTOR %1, %1, %1, %1
+ %3:_(<4 x s32>) = G_LSHR %0, %2
+ %4:_(s32) = G_CONSTANT i32 -256
+ %5:_(<4 x s32>) = G_BUILD_VECTOR %4, %4, %4, %4
+ %6:_(<4 x s32>) = G_AND %3, %5
+ $q0 = COPY %6(<4 x s32>)
+...
+---
+# trunc reads only the low 16 bits, which the AND forces to 0, so the trunc is
+# known 0 even though the wider AND result is not fully known.
+name: trunc_of_and_low_zero
+body: |
+ bb.0:
+ liveins: $w0
+ ; CHECK-LABEL: name: trunc_of_and_low_zero
+ ; CHECK: liveins: $w0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s16) = G_CONSTANT i16 0
+ ; CHECK-NEXT: $h0 = COPY [[C]](s16)
+ %0:_(s32) = COPY $w0
+ %1:_(s32) = G_CONSTANT i32 -65536
+ %2:_(s32) = G_AND %0, %1
+ %3:_(s16) = G_TRUNC %2
+ $h0 = COPY %3(s16)
+...
+---
+# zext of a known-0 narrow value (lshr result) is known 0 in the wider type.
+name: zext_of_known_zero
+body: |
+ bb.0:
+ liveins: $w0
+ ; CHECK-LABEL: name: zext_of_known_zero
+ ; CHECK: liveins: $w0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
+ ; CHECK-NEXT: $x0 = COPY [[C]](s64)
+ %0:_(s32) = COPY $w0
+ %1:_(s32) = G_CONSTANT i32 255
+ %2:_(s32) = G_AND %0, %1
+ %3:_(s32) = G_CONSTANT i32 8
+ %4:_(s32) = G_LSHR %2, %3
+ %5:_(s64) = G_ZEXT %4
+ $x0 = COPY %5(s64)
+...
+---
+# sext of a known-0 narrow value is known 0 (0 sign-extends to 0).
+name: sext_of_known_zero
+body: |
+ bb.0:
+ liveins: $w0
+ ; CHECK-LABEL: name: sext_of_known_zero
+ ; CHECK: liveins: $w0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
+ ; CHECK-NEXT: $x0 = COPY [[C]](s64)
+ %0:_(s32) = COPY $w0
+ %1:_(s32) = G_CONSTANT i32 65535
+ %2:_(s32) = G_AND %0, %1
+ %3:_(s32) = G_CONSTANT i32 16
+ %4:_(s32) = G_LSHR %2, %3
+ %5:_(s64) = G_SEXT %4
+ $x0 = COPY %5(s64)
+...
+---
+# trunc to a non-zero constant: (or x,0x0F)<<4 forces the low byte to 0xF0
+# (bits 0-3 shifted-in 0, bits 4-7 the forced ones); trunc s8 -> 0xF0.
+name: trunc_to_nonzero_const
+body: |
+ bb.0:
+ liveins: $w0
+ ; CHECK-LABEL: name: trunc_to_nonzero_const
+ ; CHECK: liveins: $w0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s8) = G_CONSTANT i8 -16
+ ; CHECK-NEXT: $b0 = COPY [[C]](s8)
+ %0:_(s32) = COPY $w0
+ %1:_(s32) = G_CONSTANT i32 15
+ %2:_(s32) = G_OR %0, %1
+ %3:_(s32) = G_CONSTANT i32 4
+ %4:_(s32) = G_SHL %2, %3
+ %5:_(s8) = G_TRUNC %4
+ $b0 = COPY %5(s8)
+...
+---
+# zext of a fully-known non-zero narrow value: the s8 (or t,0x0F)<<4 is 0xF0,
+# so zext to s32 is 0x000000F0 = 240.
+name: zext_to_nonzero_const
+body: |
+ bb.0:
+ liveins: $w0
+ ; CHECK-LABEL: name: zext_to_nonzero_const
+ ; CHECK: liveins: $w0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 240
+ ; CHECK-NEXT: $w0 = COPY [[C]](s32)
+ %0:_(s32) = COPY $w0
+ %t:_(s8) = G_TRUNC %0
+ %1:_(s8) = G_CONSTANT i8 15
+ %2:_(s8) = G_OR %t, %1
+ %3:_(s8) = G_CONSTANT i8 4
+ %4:_(s8) = G_SHL %2, %3
+ %5:_(s32) = G_ZEXT %4
+ $w0 = COPY %5(s32)
+...
+---
+# sext of the same 0xF0 s8: the sign bit is set, so sext to s32 is
+# 0xFFFFFFF0 = -16 (contrast with the zext case above).
+name: sext_to_nonzero_const
+body: |
+ bb.0:
+ liveins: $w0
+ ; CHECK-LABEL: name: sext_to_nonzero_const
+ ; CHECK: liveins: $w0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 -16
+ ; CHECK-NEXT: $w0 = COPY [[C]](s32)
+ %0:_(s32) = COPY $w0
+ %t:_(s8) = G_TRUNC %0
+ %1:_(s8) = G_CONSTANT i8 15
+ %2:_(s8) = G_OR %t, %1
+ %3:_(s8) = G_CONSTANT i8 4
+ %4:_(s8) = G_SHL %2, %3
+ %5:_(s32) = G_SEXT %4
+ $w0 = COPY %5(s32)
+...
+---
+# Negative: low 8 bits unknown, so the AND is preserved.
+name: partial_known_no_fold
+body: |
+ bb.0:
+ liveins: $w0
+ ; CHECK-LABEL: name: partial_known_no_fold
+ ; CHECK: liveins: $w0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 255
+ ; CHECK-NEXT: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY]], [[C]]
+ ; CHECK-NEXT: $w0 = COPY [[AND]](s32)
+ %0:_(s32) = COPY $w0
+ %1:_(s32) = G_CONSTANT i32 255
+ %2:_(s32) = G_AND %0, %1
+ $w0 = COPY %2(s32)
+...
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-logic-of-compare.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-logic-of-compare.mir
index 7bb166e0312c2..92d1a81098e1d 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-logic-of-compare.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-logic-of-compare.mir
@@ -386,9 +386,8 @@ body: |
; CHECK-LABEL: name: test_fcmp_and_fcmp_with_vectors
; CHECK: liveins: $x0, $x1
; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: [[C:%[0-9]+]]:_(i1) = G_CONSTANT i1 false
- ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x i1>) = G_BUILD_VECTOR [[C]](i1), [[C]](i1)
- ; CHECK-NEXT: %zext:_(<2 x i64>) = G_ZEXT [[BUILD_VECTOR]](<2 x i1>)
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(i64) = G_CONSTANT i64 0
+ ; CHECK-NEXT: %zext:_(<2 x i64>) = G_BUILD_VECTOR [[C]](i64), [[C]](i64)
; CHECK-NEXT: $q0 = COPY %zext(<2 x i64>)
%0:_(f64) = COPY $x0
%1:_(f64) = COPY $x1
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-overflow.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-overflow.mir
index df2cdb15ef899..9b98cd45da0de 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-overflow.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-overflow.mir
@@ -157,9 +157,8 @@ body: |
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i32) = COPY $w0
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(i32) = COPY $w1
; CHECK-NEXT: %bv0:_(<4 x i32>) = G_BUILD_VECTOR [[COPY]](i32), [[COPY1]](i32), [[COPY]](i32), [[COPY1]](i32)
- ; CHECK-NEXT: [[C:%[0-9]+]]:_(i1) = G_CONSTANT i1 false
- ; CHECK-NEXT: %o:_(<4 x i1>) = G_BUILD_VECTOR [[C]](i1), [[C]](i1), [[C]](i1), [[C]](i1)
- ; CHECK-NEXT: %o_wide:_(<4 x i32>) = G_ZEXT %o(<4 x i1>)
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: %o_wide:_(<4 x i32>) = G_BUILD_VECTOR [[C]](i32), [[C]](i32), [[C]](i32), [[C]](i32)
; CHECK-NEXT: $q0 = COPY %bv0(<4 x i32>)
; CHECK-NEXT: $q1 = COPY %o_wide(<4 x i32>)
; CHECK-NEXT: RET_ReallyLR implicit $w0
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-trunc.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-trunc.mir
index f478aa80e7fa2..09723b7b9959e 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-trunc.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-trunc.mir
@@ -171,14 +171,20 @@ legalized: true
body: |
bb.1:
liveins: $w0
- ; CHECK-LABEL: name: test_combine_trunc_shl_s32_by_17
- ; CHECK: liveins: $w0
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(i32) = COPY $w0
- ; CHECK-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 17
- ; CHECK-NEXT: [[SHL:%[0-9]+]]:_(i32) = G_SHL [[COPY]], [[C]](i32)
- ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(i16) = G_TRUNC [[SHL]](i32)
- ; CHECK-NEXT: $h0 = COPY [[TRUNC]](i16)
+ ; CHECK-PRE-LABEL: name: test_combine_trunc_shl_s32_by_17
+ ; CHECK-PRE: liveins: $w0
+ ; CHECK-PRE-NEXT: {{ $}}
+ ; CHECK-PRE-NEXT: [[C:%[0-9]+]]:_(i16) = G_CONSTANT i16 0
+ ; CHECK-PRE-NEXT: $h0 = COPY [[C]](i16)
+ ;
+ ; CHECK-POST-LABEL: name: test_combine_trunc_shl_s32_by_17
+ ; CHECK-POST: liveins: $w0
+ ; CHECK-POST-NEXT: {{ $}}
+ ; CHECK-POST-NEXT: [[COPY:%[0-9]+]]:_(i32) = COPY $w0
+ ; CHECK-POST-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 17
+ ; CHECK-POST-NEXT: [[SHL:%[0-9]+]]:_(i32) = G_SHL [[COPY]], [[C]](i32)
+ ; CHECK-POST-NEXT: [[TRUNC:%[0-9]+]]:_(i16) = G_TRUNC [[SHL]](i32)
+ ; CHECK-POST-NEXT: $h0 = COPY [[TRUNC]](i16)
%0:_(i32) = COPY $w0
%1:_(i32) = G_CONSTANT i32 17
%2:_(i32) = G_SHL %0(i32), %1(i32)
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-shuffle-vector-widen-crash.ll b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-shuffle-vector-widen-crash.ll
index ba53cb57c2ef2..76197f959559e 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-shuffle-vector-widen-crash.ll
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-shuffle-vector-widen-crash.ll
@@ -5,25 +5,28 @@ target triple = "arm64-apple-macosx11.0.0"
declare i32 @llvm.aarch64.neon.uaddv.i32.v4i32(<4 x i32>) #0
-define i32 @bar() {
+; The vectors are function arguments (not constants) so the shuffle result is not
+; known, ensuring the <4 x i1> shuffle still reaches the widen legalization path
+; this test guards rather than being folded to a constant beforehand.
+define i32 @bar(<8 x i1> %a, <8 x i1> %b) {
; CHECK-LABEL: bar:
; CHECK: ; %bb.0: ; %bb
-; CHECK-NEXT: movi.2d v0, #0000000000000000
+; CHECK-NEXT: ; kill: def $d0 killed $d0 def $q0
; CHECK-NEXT: umov.b w8, v0[0]
; CHECK-NEXT: umov.b w9, v0[1]
-; CHECK-NEXT: fmov s1, w8
+; CHECK-NEXT: movi.4s v1, #1
+; CHECK-NEXT: fmov s2, w8
; CHECK-NEXT: umov.b w8, v0[2]
-; CHECK-NEXT: mov.s v1[1], w9
+; CHECK-NEXT: mov.s v2[1], w9
; CHECK-NEXT: umov.b w9, v0[3]
-; CHECK-NEXT: movi.4s v0, #1
-; CHECK-NEXT: mov.s v1[2], w8
-; CHECK-NEXT: mov.s v1[3], w9
-; CHECK-NEXT: and.16b v0, v1, v0
+; CHECK-NEXT: mov.s v2[2], w8
+; CHECK-NEXT: mov.s v2[3], w9
+; CHECK-NEXT: and.16b v0, v2, v1
; CHECK-NEXT: addv.4s s0, v0
; CHECK-NEXT: fmov w0, s0
; CHECK-NEXT: ret
bb:
- %shufflevector = shufflevector <8 x i1> zeroinitializer, <8 x i1> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+ %shufflevector = shufflevector <8 x i1> %a, <8 x i1> %b, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
%zext = zext <4 x i1> %shufflevector to <4 x i32>
%call = call i32 @llvm.aarch64.neon.uaddv.i32.v4i32(<4 x i32> %zext)
%icmp = icmp eq i32 %call, 0
diff --git a/llvm/test/CodeGen/AArch64/arm64-vshift.ll b/llvm/test/CodeGen/AArch64/arm64-vshift.ll
index a7411457430c4..05db56ec848f1 100644
--- a/llvm/test/CodeGen/AArch64/arm64-vshift.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-vshift.ll
@@ -4658,8 +4658,7 @@ define <2 x i8> @shl_trunc_v2i64_v2i8(<2 x i64> %a) {
;
; CHECK-GI-LABEL: shl_trunc_v2i64_v2i8:
; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: shl v0.2d, v0.2d, #16
-; CHECK-GI-NEXT: xtn v0.2s, v0.2d
+; CHECK-GI-NEXT: movi v0.2d, #0000000000000000
; CHECK-GI-NEXT: ret
%b = shl <2 x i64> %a, <i64 16, i64 16>
%c = trunc <2 x i64> %b to <2 x i8>
diff --git a/llvm/test/CodeGen/AArch64/hadd-combine.ll b/llvm/test/CodeGen/AArch64/hadd-combine.ll
index 450069cd27428..6dbe5b2c3ecf7 100644
--- a/llvm/test/CodeGen/AArch64/hadd-combine.ll
+++ b/llvm/test/CodeGen/AArch64/hadd-combine.ll
@@ -95,19 +95,10 @@ define <8 x i16> @haddu_const_both() {
}
define <8 x i16> @haddu_const_bothhigh() {
-; CHECK-SD-LABEL: haddu_const_bothhigh:
-; CHECK-SD: // %bb.0:
-; CHECK-SD-NEXT: mvni v0.8h, #1
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: haddu_const_bothhigh:
-; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: movi d0, #0xffffffffffffffff
-; CHECK-GI-NEXT: mvni v1.4h, #1
-; CHECK-GI-NEXT: uaddl v1.4s, v1.4h, v0.4h
-; CHECK-GI-NEXT: shrn v0.4h, v1.4s, #1
-; CHECK-GI-NEXT: shrn2 v0.8h, v1.4s, #1
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: haddu_const_bothhigh:
+; CHECK: // %bb.0:
+; CHECK-NEXT: mvni v0.8h, #1
+; CHECK-NEXT: ret
%ext1 = zext <8 x i16> <i16 65534, i16 65534, i16 65534, i16 65534, i16 65534, i16 65534, i16 65534, i16 65534> to <8 x i32>
%ext2 = zext <8 x i16> <i16 65535, i16 65535, i16 65535, i16 65535, i16 65535, i16 65535, i16 65535, i16 65535> to <8 x i32>
%add = add <8 x i32> %ext1, %ext2
@@ -341,9 +332,7 @@ define <8 x i16> @hadds_const_bothhigh() {
; CHECK-GI-LABEL: hadds_const_bothhigh:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: adrp x8, .LCPI19_0
-; CHECK-GI-NEXT: mvni v0.8h, #128, lsl #8
-; CHECK-GI-NEXT: ldr q1, [x8, :lo12:.LCPI19_0]
-; CHECK-GI-NEXT: shadd v0.8h, v1.8h, v0.8h
+; CHECK-GI-NEXT: ldr q0, [x8, :lo12:.LCPI19_0]
; CHECK-GI-NEXT: ret
%ext1 = sext <8 x i16> <i16 32766, i16 32766, i16 32766, i16 32766, i16 32766, i16 32766, i16 32766, i16 32766> to <8 x i32>
%ext2 = sext <8 x i16> <i16 32767, i16 32767, i16 32767, i16 32767, i16 32767, i16 32767, i16 32767, i16 32767> to <8 x i32>
@@ -615,21 +604,10 @@ define <8 x i16> @rhaddu_const_both() {
}
define <8 x i16> @rhaddu_const_bothhigh() {
-; CHECK-SD-LABEL: rhaddu_const_bothhigh:
-; CHECK-SD: // %bb.0:
-; CHECK-SD-NEXT: movi v0.2d, #0xffffffffffffffff
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: rhaddu_const_bothhigh:
-; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: movi d0, #0xffffffffffffffff
-; CHECK-GI-NEXT: mvni v1.4h, #1
-; CHECK-GI-NEXT: movi v2.4s, #1
-; CHECK-GI-NEXT: uaddl v0.4s, v1.4h, v0.4h
-; CHECK-GI-NEXT: add v1.4s, v0.4s, v2.4s
-; CHECK-GI-NEXT: shrn v0.4h, v1.4s, #1
-; CHECK-GI-NEXT: shrn2 v0.8h, v1.4s, #1
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: rhaddu_const_bothhigh:
+; CHECK: // %bb.0:
+; CHECK-NEXT: movi v0.2d, #0xffffffffffffffff
+; CHECK-NEXT: ret
%ext1 = zext <8 x i16> <i16 65534, i16 65534, i16 65534, i16 65534, i16 65534, i16 65534, i16 65534, i16 65534> to <8 x i32>
%ext2 = zext <8 x i16> <i16 65535, i16 65535, i16 65535, i16 65535, i16 65535, i16 65535, i16 65535, i16 65535> to <8 x i32>
%add1 = add <8 x i32> %ext1, %ext2
@@ -863,18 +841,10 @@ define <8 x i16> @rhadds_const_both() {
}
define <8 x i16> @rhadds_const_bothhigh() {
-; CHECK-SD-LABEL: rhadds_const_bothhigh:
-; CHECK-SD: // %bb.0:
-; CHECK-SD-NEXT: mvni v0.8h, #128, lsl #8
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: rhadds_const_bothhigh:
-; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: adrp x8, .LCPI49_0
-; CHECK-GI-NEXT: mvni v0.8h, #128, lsl #8
-; CHECK-GI-NEXT: ldr q1, [x8, :lo12:.LCPI49_0]
-; CHECK-GI-NEXT: srhadd v0.8h, v1.8h, v0.8h
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: rhadds_const_bothhigh:
+; CHECK: // %bb.0:
+; CHECK-NEXT: mvni v0.8h, #128, lsl #8
+; CHECK-NEXT: ret
%ext1 = sext <8 x i16> <i16 32766, i16 32766, i16 32766, i16 32766, i16 32766, i16 32766, i16 32766, i16 32766> to <8 x i32>
%ext2 = sext <8 x i16> <i16 32767, i16 32767, i16 32767, i16 32767, i16 32767, i16 32767, i16 32767, i16 32767> to <8 x i32>
%add1 = add <8 x i32> %ext1, %ext2
diff --git a/llvm/test/CodeGen/AArch64/neon-compare-instructions.ll b/llvm/test/CodeGen/AArch64/neon-compare-instructions.ll
index 017f7ea0de891..ada83c54680a7 100644
--- a/llvm/test/CodeGen/AArch64/neon-compare-instructions.ll
+++ b/llvm/test/CodeGen/AArch64/neon-compare-instructions.ll
@@ -2528,9 +2528,7 @@ define <2 x i32> @fcmal2xfloat(<2 x float> %A, <2 x float> %B) {
;
; CHECK-GI-LABEL: fcmal2xfloat:
; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: movi v0.2s, #1
-; CHECK-GI-NEXT: shl v0.2s, v0.2s, #31
-; CHECK-GI-NEXT: cmlt v0.2s, v0.2s, #0
+; CHECK-GI-NEXT: movi d0, #0xffffffffffffffff
; CHECK-GI-NEXT: ret
%tmp3 = fcmp true <2 x float> %A, %B
%tmp4 = sext <2 x i1> %tmp3 to <2 x i32>
@@ -2538,34 +2536,19 @@ define <2 x i32> @fcmal2xfloat(<2 x float> %A, <2 x float> %B) {
}
define <4 x i32> @fcmal4xfloat(<4 x float> %A, <4 x float> %B) {
-; CHECK-SD-LABEL: fcmal4xfloat:
-; CHECK-SD: // %bb.0:
-; CHECK-SD-NEXT: movi v0.2d, #0xffffffffffffffff
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: fcmal4xfloat:
-; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: movi v0.4s, #1
-; CHECK-GI-NEXT: shl v0.4s, v0.4s, #31
-; CHECK-GI-NEXT: cmlt v0.4s, v0.4s, #0
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: fcmal4xfloat:
+; CHECK: // %bb.0:
+; CHECK-NEXT: movi v0.2d, #0xffffffffffffffff
+; CHECK-NEXT: ret
%tmp3 = fcmp true <4 x float> %A, %B
%tmp4 = sext <4 x i1> %tmp3 to <4 x i32>
ret <4 x i32> %tmp4
}
define <2 x i64> @fcmal2xdouble(<2 x double> %A, <2 x double> %B) {
-; CHECK-SD-LABEL: fcmal2xdouble:
-; CHECK-SD: // %bb.0:
-; CHECK-SD-NEXT: movi v0.2d, #0xffffffffffffffff
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: fcmal2xdouble:
-; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: adrp x8, .LCPI221_0
-; CHECK-GI-NEXT: ldr q0, [x8, :lo12:.LCPI221_0]
-; CHECK-GI-NEXT: shl v0.2d, v0.2d, #63
-; CHECK-GI-NEXT: cmlt v0.2d, v0.2d, #0
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: fcmal2xdouble:
+; CHECK: // %bb.0:
+; CHECK-NEXT: movi v0.2d, #0xffffffffffffffff
+; CHECK-NEXT: ret
%tmp3 = fcmp true <2 x double> %A, %B
%tmp4 = sext <2 x i1> %tmp3 to <2 x i64>
ret <2 x i64> %tmp4
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/combine-redundant-and.mir b/llvm/test/CodeGen/AMDGPU/GlobalISel/combine-redundant-and.mir
index 70bcd3d95c662..d681051edc1db 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/combine-redundant-and.mir
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/combine-redundant-and.mir
@@ -154,9 +154,8 @@ tracksRegLiveness: true
body: |
bb.0:
; CHECK-LABEL: name: test_sext_inreg
- ; CHECK: %cst_11:_(s32) = G_CONSTANT i32 11
- ; CHECK-NEXT: %sext_inreg_11:_(s32) = G_SEXT_INREG %cst_11, 4
- ; CHECK-NEXT: $sgpr0 = COPY %sext_inreg_11(s32)
+ ; CHECK: %cst_1:_(s32) = G_CONSTANT i32 -5
+ ; CHECK-NEXT: $sgpr0 = COPY %cst_1(s32)
; CHECK-NEXT: SI_RETURN_TO_EPILOG implicit $sgpr0
%cst_1:_(s32) = G_CONSTANT i32 -5
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/combine-shl-from-extend-narrow.postlegal.mir b/llvm/test/CodeGen/AMDGPU/GlobalISel/combine-shl-from-extend-narrow.postlegal.mir
index 5a337b251bab6..e5db8de4e4ef8 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/combine-shl-from-extend-narrow.postlegal.mir
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/combine-shl-from-extend-narrow.postlegal.mir
@@ -375,15 +375,15 @@ body: |
; GFX6: liveins: $vgpr0
; GFX6-NEXT: {{ $}}
; GFX6-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
- ; GFX6-NEXT: %shl:_(<2 x s32>) = G_BUILD_VECTOR [[C]](s32), [[C]](s32)
- ; GFX6-NEXT: $vgpr0_vgpr1 = COPY %shl(<2 x s32>)
+ ; GFX6-NEXT: %extend:_(<2 x s32>) = G_BUILD_VECTOR [[C]](s32), [[C]](s32)
+ ; GFX6-NEXT: $vgpr0_vgpr1 = COPY %extend(<2 x s32>)
;
; GFX9-LABEL: name: do_not_shl_v2s32_zero_by_16_from_zext_v2s16
; GFX9: liveins: $vgpr0
; GFX9-NEXT: {{ $}}
; GFX9-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
- ; GFX9-NEXT: %shl:_(<2 x s32>) = G_BUILD_VECTOR [[C]](s32), [[C]](s32)
- ; GFX9-NEXT: $vgpr0_vgpr1 = COPY %shl(<2 x s32>)
+ ; GFX9-NEXT: %extend:_(<2 x s32>) = G_BUILD_VECTOR [[C]](s32), [[C]](s32)
+ ; GFX9-NEXT: $vgpr0_vgpr1 = COPY %extend(<2 x s32>)
%zero:_(s16) = G_CONSTANT i16 0
%zerovector:_(<2 x s16>) = G_BUILD_VECTOR %zero, %zero:_(s16)
%shiftamt:_(s16) = G_CONSTANT i16 16
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/combine-shl-from-extend-narrow.prelegal.mir b/llvm/test/CodeGen/AMDGPU/GlobalISel/combine-shl-from-extend-narrow.prelegal.mir
index 25feacdca01ce..628ac494b1304 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/combine-shl-from-extend-narrow.prelegal.mir
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/combine-shl-from-extend-narrow.prelegal.mir
@@ -246,16 +246,16 @@ body: |
; GFX6-LABEL: name: do_not_shl_v2s32_zero_by_16_from_zext_v2s16
; GFX6: liveins: $vgpr0, $vgpr1
; GFX6-NEXT: {{ $}}
- ; GFX6-NEXT: %6:_(s32) = G_CONSTANT i32 0
- ; GFX6-NEXT: %shl:_(<2 x s32>) = G_BUILD_VECTOR %6(s32), %6(s32)
- ; GFX6-NEXT: $vgpr0_vgpr1 = COPY %shl(<2 x s32>)
+ ; GFX6-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; GFX6-NEXT: %extend:_(<2 x s32>) = G_BUILD_VECTOR [[C]](s32), [[C]](s32)
+ ; GFX6-NEXT: $vgpr0_vgpr1 = COPY %extend(<2 x s32>)
;
; GFX9-LABEL: name: do_not_shl_v2s32_zero_by_16_from_zext_v2s16
; GFX9: liveins: $vgpr0, $vgpr1
; GFX9-NEXT: {{ $}}
- ; GFX9-NEXT: %6:_(s32) = G_CONSTANT i32 0
- ; GFX9-NEXT: %shl:_(<2 x s32>) = G_BUILD_VECTOR %6(s32), %6(s32)
- ; GFX9-NEXT: $vgpr0_vgpr1 = COPY %shl(<2 x s32>)
+ ; GFX9-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
+ ; GFX9-NEXT: %extend:_(<2 x s32>) = G_BUILD_VECTOR [[C]](s32), [[C]](s32)
+ ; GFX9-NEXT: $vgpr0_vgpr1 = COPY %extend(<2 x s32>)
%zero:_(s16) = G_CONSTANT i16 0
%zerovector:_(<2 x s16>) = G_BUILD_VECTOR %zero, %zero:_(s16)
%shiftamt:_(s16) = G_CONSTANT i16 16
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/combine-short-clamp-inverted-bounds.mir b/llvm/test/CodeGen/AMDGPU/GlobalISel/combine-short-clamp-inverted-bounds.mir
index 924b58f720444..3601b23cce831 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/combine-short-clamp-inverted-bounds.mir
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/combine-short-clamp-inverted-bounds.mir
@@ -1,8 +1,12 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
-# RUN: llc -mtriple=amdgpu9.00-amd-amdhsa -run-pass=amdgpu-prelegalizer-combiner -verify-machineinstrs %s -o - | FileCheck %s
+# RUN: llc -mtriple=amdgpu9.00-amd-amdhsa -run-pass=amdgpu-prelegalizer-combiner -verify-machineinstrs \
+# RUN: --amdgpuprelegalizercombiner-disable-rule=known_bits_to_constant %s -o - | FileCheck %s
+# REQUIRES: asserts
# matchClampI64ToI16 must not fire on inverted bounds: smin(smax(x,100),0) is
-# constant 0, not a [0,100] clamp.
+# constant 0, not a [0,100] clamp. known_bits_to_constant is disabled here so the
+# clamp matcher is exercised on the min/max sequence instead of the folded
+# constant.
---
name: clamp_i64_i16_inverted_bounds
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/llvm.amdgcn.make.buffer.rsrc.ll b/llvm/test/CodeGen/AMDGPU/GlobalISel/llvm.amdgcn.make.buffer.rsrc.ll
index 04cdd48f8f78e..34bba77dbb799 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/llvm.amdgcn.make.buffer.rsrc.ll
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/llvm.amdgcn.make.buffer.rsrc.ll
@@ -34,28 +34,23 @@ define amdgpu_ps ptr addrspace(8) @basic_raw_buffer(ptr inreg %p) {
; CHECK45-NEXT: [[COPY:%[0-9]+]]:sreg_32 = COPY $sgpr0
; CHECK45-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr1
; CHECK45-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1
- ; CHECK45-NEXT: [[S_MOV_B32_:%[0-9]+]]:sreg_32 = S_MOV_B32 0
; CHECK45-NEXT: [[S_MOV_B:%[0-9]+]]:sreg_64 = S_MOV_B64_IMM_PSEUDO -6629298651489370112
; CHECK45-NEXT: [[S_OR_B64_:%[0-9]+]]:sreg_64 = S_OR_B64 [[REG_SEQUENCE]], [[S_MOV_B]], implicit-def dead $scc
- ; CHECK45-NEXT: [[S_MOV_B64_:%[0-9]+]]:sreg_64 = S_MOV_B64 9
- ; CHECK45-NEXT: [[S_MOV_B32_1:%[0-9]+]]:sreg_32 = S_MOV_B32 -536870912
- ; CHECK45-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[S_MOV_B32_]], %subreg.sub0, [[S_MOV_B32_1]], %subreg.sub1
- ; CHECK45-NEXT: [[S_OR_B64_1:%[0-9]+]]:sreg_64 = S_OR_B64 [[REG_SEQUENCE1]], [[S_MOV_B64_]], implicit-def dead $scc
; CHECK45-NEXT: [[COPY2:%[0-9]+]]:sreg_32 = COPY [[S_OR_B64_]].sub0
; CHECK45-NEXT: [[COPY3:%[0-9]+]]:sreg_32 = COPY [[S_OR_B64_]].sub1
- ; CHECK45-NEXT: [[COPY4:%[0-9]+]]:sreg_32 = COPY [[S_OR_B64_1]].sub0
- ; CHECK45-NEXT: [[COPY5:%[0-9]+]]:sreg_32 = COPY [[S_OR_B64_1]].sub1
- ; CHECK45-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY [[COPY2]]
- ; CHECK45-NEXT: [[V_READFIRSTLANE_B32_:%[0-9]+]]:sreg_32_xm0 = V_READFIRSTLANE_B32 [[COPY6]], implicit $exec
+ ; CHECK45-NEXT: [[S_MOV_B32_:%[0-9]+]]:sreg_32 = S_MOV_B32 9
+ ; CHECK45-NEXT: [[S_MOV_B32_1:%[0-9]+]]:sreg_32 = S_MOV_B32 -536870912
+ ; CHECK45-NEXT: [[COPY4:%[0-9]+]]:vgpr_32 = COPY [[COPY2]]
+ ; CHECK45-NEXT: [[V_READFIRSTLANE_B32_:%[0-9]+]]:sreg_32_xm0 = V_READFIRSTLANE_B32 [[COPY4]], implicit $exec
; CHECK45-NEXT: $sgpr0 = COPY [[V_READFIRSTLANE_B32_]]
- ; CHECK45-NEXT: [[COPY7:%[0-9]+]]:vgpr_32 = COPY [[COPY3]]
- ; CHECK45-NEXT: [[V_READFIRSTLANE_B32_1:%[0-9]+]]:sreg_32_xm0 = V_READFIRSTLANE_B32 [[COPY7]], implicit $exec
+ ; CHECK45-NEXT: [[COPY5:%[0-9]+]]:vgpr_32 = COPY [[COPY3]]
+ ; CHECK45-NEXT: [[V_READFIRSTLANE_B32_1:%[0-9]+]]:sreg_32_xm0 = V_READFIRSTLANE_B32 [[COPY5]], implicit $exec
; CHECK45-NEXT: $sgpr1 = COPY [[V_READFIRSTLANE_B32_1]]
- ; CHECK45-NEXT: [[COPY8:%[0-9]+]]:vgpr_32 = COPY [[COPY4]]
- ; CHECK45-NEXT: [[V_READFIRSTLANE_B32_2:%[0-9]+]]:sreg_32_xm0 = V_READFIRSTLANE_B32 [[COPY8]], implicit $exec
+ ; CHECK45-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY [[S_MOV_B32_]]
+ ; CHECK45-NEXT: [[V_READFIRSTLANE_B32_2:%[0-9]+]]:sreg_32_xm0 = V_READFIRSTLANE_B32 [[COPY6]], implicit $exec
; CHECK45-NEXT: $sgpr2 = COPY [[V_READFIRSTLANE_B32_2]]
- ; CHECK45-NEXT: [[COPY9:%[0-9]+]]:vgpr_32 = COPY [[COPY5]]
- ; CHECK45-NEXT: [[V_READFIRSTLANE_B32_3:%[0-9]+]]:sreg_32_xm0 = V_READFIRSTLANE_B32 [[COPY9]], implicit $exec
+ ; CHECK45-NEXT: [[COPY7:%[0-9]+]]:vgpr_32 = COPY [[S_MOV_B32_1]]
+ ; CHECK45-NEXT: [[V_READFIRSTLANE_B32_3:%[0-9]+]]:sreg_32_xm0 = V_READFIRSTLANE_B32 [[COPY7]], implicit $exec
; CHECK45-NEXT: $sgpr3 = COPY [[V_READFIRSTLANE_B32_3]]
; CHECK45-NEXT: SI_RETURN_TO_EPILOG implicit $sgpr0, implicit $sgpr1, implicit $sgpr2, implicit $sgpr3
%rsrc = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr %p, i16 0, i64 1234, i32 5678)
@@ -94,28 +89,23 @@ define amdgpu_ps ptr addrspace(8) @large_num_records_raw_buffer(ptr inreg %p) {
; CHECK45-NEXT: [[COPY:%[0-9]+]]:sreg_32 = COPY $sgpr0
; CHECK45-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr1
; CHECK45-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1
- ; CHECK45-NEXT: [[S_MOV_B32_:%[0-9]+]]:sreg_32 = S_MOV_B32 0
; CHECK45-NEXT: [[S_MOV_B:%[0-9]+]]:sreg_64 = S_MOV_B64_IMM_PSEUDO -6629298651489370112
; CHECK45-NEXT: [[S_OR_B64_:%[0-9]+]]:sreg_64 = S_OR_B64 [[REG_SEQUENCE]], [[S_MOV_B]], implicit-def dead $scc
- ; CHECK45-NEXT: [[S_MOV_B1:%[0-9]+]]:sreg_64 = S_MOV_B64_IMM_PSEUDO 33554441
- ; CHECK45-NEXT: [[S_MOV_B32_1:%[0-9]+]]:sreg_32 = S_MOV_B32 -536870912
- ; CHECK45-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[S_MOV_B32_]], %subreg.sub0, [[S_MOV_B32_1]], %subreg.sub1
- ; CHECK45-NEXT: [[S_OR_B64_1:%[0-9]+]]:sreg_64 = S_OR_B64 [[REG_SEQUENCE1]], [[S_MOV_B1]], implicit-def dead $scc
; CHECK45-NEXT: [[COPY2:%[0-9]+]]:sreg_32 = COPY [[S_OR_B64_]].sub0
; CHECK45-NEXT: [[COPY3:%[0-9]+]]:sreg_32 = COPY [[S_OR_B64_]].sub1
- ; CHECK45-NEXT: [[COPY4:%[0-9]+]]:sreg_32 = COPY [[S_OR_B64_1]].sub0
- ; CHECK45-NEXT: [[COPY5:%[0-9]+]]:sreg_32 = COPY [[S_OR_B64_1]].sub1
- ; CHECK45-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY [[COPY2]]
- ; CHECK45-NEXT: [[V_READFIRSTLANE_B32_:%[0-9]+]]:sreg_32_xm0 = V_READFIRSTLANE_B32 [[COPY6]], implicit $exec
+ ; CHECK45-NEXT: [[S_MOV_B32_:%[0-9]+]]:sreg_32 = S_MOV_B32 33554441
+ ; CHECK45-NEXT: [[S_MOV_B32_1:%[0-9]+]]:sreg_32 = S_MOV_B32 -536870912
+ ; CHECK45-NEXT: [[COPY4:%[0-9]+]]:vgpr_32 = COPY [[COPY2]]
+ ; CHECK45-NEXT: [[V_READFIRSTLANE_B32_:%[0-9]+]]:sreg_32_xm0 = V_READFIRSTLANE_B32 [[COPY4]], implicit $exec
; CHECK45-NEXT: $sgpr0 = COPY [[V_READFIRSTLANE_B32_]]
- ; CHECK45-NEXT: [[COPY7:%[0-9]+]]:vgpr_32 = COPY [[COPY3]]
- ; CHECK45-NEXT: [[V_READFIRSTLANE_B32_1:%[0-9]+]]:sreg_32_xm0 = V_READFIRSTLANE_B32 [[COPY7]], implicit $exec
+ ; CHECK45-NEXT: [[COPY5:%[0-9]+]]:vgpr_32 = COPY [[COPY3]]
+ ; CHECK45-NEXT: [[V_READFIRSTLANE_B32_1:%[0-9]+]]:sreg_32_xm0 = V_READFIRSTLANE_B32 [[COPY5]], implicit $exec
; CHECK45-NEXT: $sgpr1 = COPY [[V_READFIRSTLANE_B32_1]]
- ; CHECK45-NEXT: [[COPY8:%[0-9]+]]:vgpr_32 = COPY [[COPY4]]
- ; CHECK45-NEXT: [[V_READFIRSTLANE_B32_2:%[0-9]+]]:sreg_32_xm0 = V_READFIRSTLANE_B32 [[COPY8]], implicit $exec
+ ; CHECK45-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY [[S_MOV_B32_]]
+ ; CHECK45-NEXT: [[V_READFIRSTLANE_B32_2:%[0-9]+]]:sreg_32_xm0 = V_READFIRSTLANE_B32 [[COPY6]], implicit $exec
; CHECK45-NEXT: $sgpr2 = COPY [[V_READFIRSTLANE_B32_2]]
- ; CHECK45-NEXT: [[COPY9:%[0-9]+]]:vgpr_32 = COPY [[COPY5]]
- ; CHECK45-NEXT: [[V_READFIRSTLANE_B32_3:%[0-9]+]]:sreg_32_xm0 = V_READFIRSTLANE_B32 [[COPY9]], implicit $exec
+ ; CHECK45-NEXT: [[COPY7:%[0-9]+]]:vgpr_32 = COPY [[S_MOV_B32_1]]
+ ; CHECK45-NEXT: [[V_READFIRSTLANE_B32_3:%[0-9]+]]:sreg_32_xm0 = V_READFIRSTLANE_B32 [[COPY7]], implicit $exec
; CHECK45-NEXT: $sgpr3 = COPY [[V_READFIRSTLANE_B32_3]]
; CHECK45-NEXT: SI_RETURN_TO_EPILOG implicit $sgpr0, implicit $sgpr1, implicit $sgpr2, implicit $sgpr3
%rsrc = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr %p, i16 0, i64 4294968530, i32 5678)
@@ -385,31 +375,23 @@ define amdgpu_ps ptr addrspace(8) @basic_struct_buffer(ptr inreg %p) {
; CHECK45-NEXT: [[COPY:%[0-9]+]]:sreg_32 = COPY $sgpr0
; CHECK45-NEXT: [[COPY1:%[0-9]+]]:sreg_32 = COPY $sgpr1
; CHECK45-NEXT: [[REG_SEQUENCE:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[COPY]], %subreg.sub0, [[COPY1]], %subreg.sub1
- ; CHECK45-NEXT: [[S_MOV_B32_:%[0-9]+]]:sreg_32 = S_MOV_B32 0
; CHECK45-NEXT: [[S_MOV_B:%[0-9]+]]:sreg_64 = S_MOV_B64_IMM_PSEUDO -6629298651489370112
; CHECK45-NEXT: [[S_OR_B64_:%[0-9]+]]:sreg_64 = S_OR_B64 [[REG_SEQUENCE]], [[S_MOV_B]], implicit-def dead $scc
- ; CHECK45-NEXT: [[S_MOV_B64_:%[0-9]+]]:sreg_64 = S_MOV_B64 9
- ; CHECK45-NEXT: [[S_MOV_B32_1:%[0-9]+]]:sreg_32 = S_MOV_B32 16384
- ; CHECK45-NEXT: [[REG_SEQUENCE1:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[S_MOV_B32_]], %subreg.sub0, [[S_MOV_B32_1]], %subreg.sub1
- ; CHECK45-NEXT: [[S_MOV_B32_2:%[0-9]+]]:sreg_32 = S_MOV_B32 -536870912
- ; CHECK45-NEXT: [[REG_SEQUENCE2:%[0-9]+]]:sreg_64 = REG_SEQUENCE [[S_MOV_B32_]], %subreg.sub0, [[S_MOV_B32_2]], %subreg.sub1
- ; CHECK45-NEXT: [[S_OR_B64_1:%[0-9]+]]:sreg_64 = S_OR_B64 [[REG_SEQUENCE1]], [[S_MOV_B64_]], implicit-def dead $scc
- ; CHECK45-NEXT: [[S_OR_B64_2:%[0-9]+]]:sreg_64 = S_OR_B64 [[S_OR_B64_1]], [[REG_SEQUENCE2]], implicit-def dead $scc
; CHECK45-NEXT: [[COPY2:%[0-9]+]]:sreg_32 = COPY [[S_OR_B64_]].sub0
; CHECK45-NEXT: [[COPY3:%[0-9]+]]:sreg_32 = COPY [[S_OR_B64_]].sub1
- ; CHECK45-NEXT: [[COPY4:%[0-9]+]]:sreg_32 = COPY [[S_OR_B64_2]].sub0
- ; CHECK45-NEXT: [[COPY5:%[0-9]+]]:sreg_32 = COPY [[S_OR_B64_2]].sub1
- ; CHECK45-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY [[COPY2]]
- ; CHECK45-NEXT: [[V_READFIRSTLANE_B32_:%[0-9]+]]:sreg_32_xm0 = V_READFIRSTLANE_B32 [[COPY6]], implicit $exec
+ ; CHECK45-NEXT: [[S_MOV_B32_:%[0-9]+]]:sreg_32 = S_MOV_B32 9
+ ; CHECK45-NEXT: [[S_MOV_B32_1:%[0-9]+]]:sreg_32 = S_MOV_B32 -536854528
+ ; CHECK45-NEXT: [[COPY4:%[0-9]+]]:vgpr_32 = COPY [[COPY2]]
+ ; CHECK45-NEXT: [[V_READFIRSTLANE_B32_:%[0-9]+]]:sreg_32_xm0 = V_READFIRSTLANE_B32 [[COPY4]], implicit $exec
; CHECK45-NEXT: $sgpr0 = COPY [[V_READFIRSTLANE_B32_]]
- ; CHECK45-NEXT: [[COPY7:%[0-9]+]]:vgpr_32 = COPY [[COPY3]]
- ; CHECK45-NEXT: [[V_READFIRSTLANE_B32_1:%[0-9]+]]:sreg_32_xm0 = V_READFIRSTLANE_B32 [[COPY7]], implicit $exec
+ ; CHECK45-NEXT: [[COPY5:%[0-9]+]]:vgpr_32 = COPY [[COPY3]]
+ ; CHECK45-NEXT: [[V_READFIRSTLANE_B32_1:%[0-9]+]]:sreg_32_xm0 = V_READFIRSTLANE_B32 [[COPY5]], implicit $exec
; CHECK45-NEXT: $sgpr1 = COPY [[V_READFIRSTLANE_B32_1]]
- ; CHECK45-NEXT: [[COPY8:%[0-9]+]]:vgpr_32 = COPY [[COPY4]]
- ; CHECK45-NEXT: [[V_READFIRSTLANE_B32_2:%[0-9]+]]:sreg_32_xm0 = V_READFIRSTLANE_B32 [[COPY8]], implicit $exec
+ ; CHECK45-NEXT: [[COPY6:%[0-9]+]]:vgpr_32 = COPY [[S_MOV_B32_]]
+ ; CHECK45-NEXT: [[V_READFIRSTLANE_B32_2:%[0-9]+]]:sreg_32_xm0 = V_READFIRSTLANE_B32 [[COPY6]], implicit $exec
; CHECK45-NEXT: $sgpr2 = COPY [[V_READFIRSTLANE_B32_2]]
- ; CHECK45-NEXT: [[COPY9:%[0-9]+]]:vgpr_32 = COPY [[COPY5]]
- ; CHECK45-NEXT: [[V_READFIRSTLANE_B32_3:%[0-9]+]]:sreg_32_xm0 = V_READFIRSTLANE_B32 [[COPY9]], implicit $exec
+ ; CHECK45-NEXT: [[COPY7:%[0-9]+]]:vgpr_32 = COPY [[S_MOV_B32_1]]
+ ; CHECK45-NEXT: [[V_READFIRSTLANE_B32_3:%[0-9]+]]:sreg_32_xm0 = V_READFIRSTLANE_B32 [[COPY7]], implicit $exec
; CHECK45-NEXT: $sgpr3 = COPY [[V_READFIRSTLANE_B32_3]]
; CHECK45-NEXT: SI_RETURN_TO_EPILOG implicit $sgpr0, implicit $sgpr1, implicit $sgpr2, implicit $sgpr3
%rsrc = call ptr addrspace(8) @llvm.amdgcn.make.buffer.rsrc.p8.p0.i64(ptr %p, i16 4, i64 1234, i32 5678)
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/rotl-rotr.ll b/llvm/test/CodeGen/RISCV/GlobalISel/rotl-rotr.ll
index 91cbf477efc03..4cafae8fab60b 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/rotl-rotr.ll
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/rotl-rotr.ll
@@ -1,16 +1,27 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-; RUN: llc -mtriple=riscv32 -verify-machineinstrs -global-isel < %s \
+; RUN: llc -mtriple=riscv32 -verify-machineinstrs -global-isel \
+; RUN: --riscvprelegalizercombiner-disable-rule=known_bits_to_constant < %s \
; RUN: | FileCheck %s -check-prefix=RV32I
-; RUN: llc -mtriple=riscv64 -verify-machineinstrs -enable-legalize-types-checking -global-isel < %s \
+; RUN: llc -mtriple=riscv64 -verify-machineinstrs -enable-legalize-types-checking -global-isel \
+; RUN: --riscvprelegalizercombiner-disable-rule=known_bits_to_constant < %s \
; RUN: | FileCheck %s -check-prefix=RV64I
-; RUN: llc -mtriple=riscv32 -mattr=+zbb -verify-machineinstrs -global-isel < %s \
+; RUN: llc -mtriple=riscv32 -mattr=+zbb -verify-machineinstrs -global-isel \
+; RUN: --riscvprelegalizercombiner-disable-rule=known_bits_to_constant < %s \
; RUN: | FileCheck %s -check-prefix=RV32ZBB
-; RUN: llc -mtriple=riscv64 -mattr=+zbb -verify-machineinstrs -global-isel < %s \
+; RUN: llc -mtriple=riscv64 -mattr=+zbb -verify-machineinstrs -global-isel \
+; RUN: --riscvprelegalizercombiner-disable-rule=known_bits_to_constant < %s \
; RUN: | FileCheck %s -check-prefix=RV64ZBB
-; RUN: llc -mtriple=riscv32 -mattr=+xtheadbb -verify-machineinstrs -global-isel < %s \
+; RUN: llc -mtriple=riscv32 -mattr=+xtheadbb -verify-machineinstrs -global-isel \
+; RUN: --riscvprelegalizercombiner-disable-rule=known_bits_to_constant < %s \
; RUN: | FileCheck %s -check-prefix=RV32XTHEADBB
-; RUN: llc -mtriple=riscv64 -mattr=+xtheadbb -verify-machineinstrs -global-isel < %s \
+; RUN: llc -mtriple=riscv64 -mattr=+xtheadbb -verify-machineinstrs -global-isel \
+; RUN: --riscvprelegalizercombiner-disable-rule=known_bits_to_constant < %s \
; RUN: | FileCheck %s -check-prefix=RV64XTHEADBB
+; REQUIRES: asserts
+
+; NOTE: The *_mask_or_* functions use over-shift amounts (e.g. y|64), which
+; known_bits_to_constant would fold to a constant, hiding the shift-amount
+; masking. Disable that rule so the real lowering is tested.
; NOTE: -enable-legalize-types-checking is on one command line due to a previous
; assertion failure on an expensive checks build for @rotr_32_mask_multiple.
More information about the llvm-commits
mailing list