[llvm] [GlobalISel][TableGen] Add GIReplaceRegWithConstant/FConstant builtins (PR #222298)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 9 04:06:45 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-globalisel
Author: Vikash Gupta (vg0204)
<details>
<summary>Changes</summary>
It adds apply-only MIR-pattern builtins feature that replace a match-root register with a fresh `G_CONSTANT` or `G_FCONSTANT` of the same type, including splat for fixed-vector destinations. Thus, it eliminates the need for `replaceInstWithConstant/replaceInstWithFConstant` C++ helpers.
---
Patch is 35.43 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/222298.diff
17 Files Affected:
- (modified) llvm/docs/GlobalISel/MIRPatterns.md (+64)
- (modified) llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h (+5)
- (modified) llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h (+15)
- (modified) llvm/include/llvm/Target/GlobalISel/Combine.td (+38-6)
- (modified) llvm/test/CodeGen/AArch64/GlobalISel/combine-binop-undef-left-to-zero.mir (+8-8)
- (modified) llvm/test/CodeGen/AArch64/GlobalISel/combine-constant-fold-itofp-zero.mir (+4-4)
- (added) llvm/test/CodeGen/AArch64/GlobalISel/combine-replacereg-fconstant-widths.mir (+208)
- (modified) llvm/test/CodeGen/AArch64/GlobalISel/combine-unary-undef-to-zero.mir (+4-4)
- (modified) llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-hoist-same-hands.mir (+2-2)
- (modified) llvm/test/TableGen/GlobalISelCombinerEmitter/builtins/builtin-pattern-errors.td (+61-1)
- (modified) llvm/test/TableGen/GlobalISelCombinerEmitter/builtins/builtin-pattern-parrsing.td (+22-1)
- (added) llvm/test/TableGen/GlobalISelCombinerEmitter/builtins/match-table-replacereg-fconstant.td (+51)
- (modified) llvm/utils/TableGen/Common/GlobalISel/MatchTable/Matchers.cpp (+9)
- (modified) llvm/utils/TableGen/Common/GlobalISel/MatchTable/Matchers.h (+18)
- (modified) llvm/utils/TableGen/Common/GlobalISel/Patterns.cpp (+13-1)
- (modified) llvm/utils/TableGen/Common/GlobalISel/Patterns.h (+5-1)
- (modified) llvm/utils/TableGen/GlobalISelCombinerEmitter.cpp (+41-2)
``````````diff
diff --git a/llvm/docs/GlobalISel/MIRPatterns.md b/llvm/docs/GlobalISel/MIRPatterns.md
index 8253edf463562..0e556873cf5da 100644
--- a/llvm/docs/GlobalISel/MIRPatterns.md
+++ b/llvm/docs/GlobalISel/MIRPatterns.md
@@ -211,6 +211,51 @@ Semantics:
- If both old/new are operands of matched instructions,
`canReplaceReg` is checked before applying the rule.
+#### GIReplaceRegWithConstant
+
+```{code-block} text
+:caption: Usage
+
+(apply (GIReplaceRegWithConstant $reg, Imm))
+```
+
+Operands:
+
+- `$reg` (out) register defined by the match root
+- `Imm`: an integer literal
+
+Semantics:
+
+- Can only appear in an 'apply' pattern.
+- `$reg` must be a register defined by the match root.
+- Replaces all uses of `$reg` with a fresh constant of `$reg`'s type. If that
+ type is a fixed vector, the constant is splatted across all lanes.
+
+#### GIReplaceRegWithFConstant
+
+```{code-block} text
+:caption: Usage
+
+(apply (GIReplaceRegWithFConstant $reg, Imm))
+```
+
+Operands:
+
+- `$reg` (out) register defined by the match root
+- `Imm`: an integer literal
+
+```{warning}
+`Imm` is the **IEEE bit pattern** of `$reg`'s (scalar) type, not a decimal fp
+value: e.g. for an f32 `$reg`, `0` means `+0.0` (bit pattern `0x00000000`).
+```
+
+Semantics:
+
+- Can only appear in an 'apply' pattern.
+- `$reg` must be a register defined by the match root.
+- Replaces all uses of `$reg` with a fresh `G_FCONSTANT` of `$reg`'s type. If
+ that type is a fixed vector, the constant is splatted across all lanes.
+
#### GIEraseRoot
```{code-block} text
@@ -423,6 +468,25 @@ def ReplaceTemp : GICombineRule<
(GIReplaceReg $b, $new))>
```
+#### Common Pattern #1b: Replace a Register with a Constant
+
+To replace a match root's def with a fresh constant, use
+`GIReplaceRegWithConstant` (or `GIReplaceRegWithFConstant` for a
+`G_FCONSTANT`, where `Imm` is an IEEE bit pattern rather than a decimal fp
+value).
+
+```text
+def Foo : GICombineRule<
+ (defs root:$dst),
+ (match (G_AND $dst, $x, $undef):$mi, (G_IMPLICIT_DEF $undef)),
+ (apply (GIReplaceRegWithConstant $dst, 0))>;
+
+def Bar : GICombineRule<
+ (defs root:$dst),
+ (match (G_UITOFP $dst, 0)),
+ (apply (GIReplaceRegWithFConstant $dst, 0))>;
+```
+
#### Common Pattern #2: Erasing a Def-less Root
If we simply want to erase a def-less match root, we can use the
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h
index 6e3ccf1923c40..786594374ed2b 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h
@@ -384,6 +384,11 @@ enum {
/// - Imm(8) - The immediate to add
GIR_BuildConstant,
+ /// Builds an FP constant and stores its result in a TempReg.
+ /// - TempRegID(ULEB128) - Temp Register to define.
+ /// - Imm(8) - IEEE bit pattern of the TempReg's (scalar) type.
+ GIR_BuildFConstant,
+
/// Copy an operand to the specified instruction
/// - NewInsnID(ULEB128) - Instruction ID to modify
/// - OldInsnID(ULEB128) - Instruction ID to copy from
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h
index 905fe847223f7..9281dc6bc5304 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h
@@ -20,6 +20,7 @@
#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
#include "llvm/CodeGen/GlobalISel/Utils.h"
+#include "llvm/CodeGen/LowLevelTypeUtils.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
@@ -1123,6 +1124,20 @@ bool GIMatchTableExecutor::executeMatchTable(
break;
}
+ case GIR_BuildFConstant: {
+ uint64_t TempRegID = readULEB();
+ uint64_t Bits = readU64();
+ initializeBuilder();
+ Register TempReg = State.TempRegisters[TempRegID];
+ LLT Ty = MRI.getType(TempReg).getScalarType();
+ APFloat Val(getFltSemanticForLLT(Ty), APInt(Ty.getSizeInBits(), Bits));
+ Builder.buildFConstant(TempReg, Val);
+ DEBUG_WITH_TYPE(TgtExecutor::getName(),
+ dbgs() << CurrentIdx << ": GIR_BuildFConstant(TempReg["
+ << TempRegID << "], Bits=" << Bits << ")\n");
+ break;
+ }
+
case GIR_RootToRootCopy:
case GIR_Copy: {
uint64_t NewInsnID =
diff --git a/llvm/include/llvm/Target/GlobalISel/Combine.td b/llvm/include/llvm/Target/GlobalISel/Combine.td
index 3735e95ee8f68..773696669ea06 100644
--- a/llvm/include/llvm/Target/GlobalISel/Combine.td
+++ b/llvm/include/llvm/Target/GlobalISel/Combine.td
@@ -162,6 +162,38 @@ class GIBuiltinInst;
// "canReplaceReg" is checked before applying the rule.
def GIReplaceReg : GIBuiltinInst;
+// Replace a register defined by the match root with a fresh G_CONSTANT.
+// Splatted across all lanes if the type is a fixed vector.
+//
+// Usage:
+// (apply (GIReplaceRegWithConstant $reg, Imm))
+//
+// Operands:
+// - $reg (out) register defined by the match root
+// - Imm: an integer literal
+//
+// Semantics:
+// - Can only appear in an 'apply' pattern.
+// - $reg must be a register defined by the match root.
+def GIReplaceRegWithConstant : GIBuiltinInst;
+
+// Replace a register defined by the match root with a fresh G_FCONSTANT.
+// Splatted across all lanes if the type is a fixed vector.
+//
+// Usage:
+// (apply (GIReplaceRegWithFConstant $reg, Imm))
+//
+// Operands:
+// - $reg (out) register defined by the match root
+// - Imm: an integer literal, interpreted as the IEEE bit pattern of $reg's
+// (scalar) type, not a decimal fp value: e.g. for an f32 $reg, `0` means
+// the bit pattern 0x00000000 (i.e. +0.0).
+//
+// Semantics:
+// - Can only appear in an 'apply' pattern.
+// - $reg must be a register defined by the match root.
+def GIReplaceRegWithFConstant : GIBuiltinInst;
+
// Apply action that erases the match root.
//
// Usage:
@@ -513,25 +545,25 @@ def undef_to_fp_zero_frags : unary_undef_frag<[G_UITOFP, G_SITOFP]>;
def undef_to_fp_zero : GICombineRule<
(defs root:$dst),
(match (undef_to_fp_zero_frags $dst)),
- (apply [{ Helper.replaceInstWithFConstant(*${dst}.getParent(), 0.0); }])>;
+ (apply (GIReplaceRegWithFConstant $dst, 0))>;
def undef_to_int_zero_frags : binop_any_undef_frag<[G_AND, G_MUL]>;
def undef_to_int_zero: GICombineRule<
(defs root:$dst),
(match (undef_to_int_zero_frags $dst)),
- (apply [{ Helper.replaceInstWithConstant(*${dst}.getParent(), 0); }])>;
+ (apply (GIReplaceRegWithConstant $dst, 0))>;
def undef_to_negative_one_frags : binop_any_undef_frag<[G_OR]>;
def undef_to_negative_one: GICombineRule<
(defs root:$dst),
(match (undef_to_negative_one_frags $dst)),
- (apply [{ Helper.replaceInstWithConstant(*${dst}.getParent(), -1); }])>;
+ (apply (GIReplaceRegWithConstant $dst, -1))>;
def binop_left_undef_to_zero_frags : binop_left_undef_frag<[G_SHL, G_UDIV, G_UREM]>;
def binop_left_undef_to_zero: GICombineRule<
(defs root:$dst),
(match (binop_left_undef_to_zero_frags $dst)),
- (apply [{ Helper.replaceInstWithConstant(*${dst}.getParent(), 0); }])>;
+ (apply (GIReplaceRegWithConstant $dst, 0))>;
def binop_right_undef_to_undef_frags : binop_right_undef_frag<[G_SHL, G_ASHR, G_LSHR]>;
def binop_right_undef_to_undef: GICombineRule<
@@ -543,7 +575,7 @@ def unary_undef_to_zero_frags : unary_undef_frag<[G_ABS]>;
def unary_undef_to_zero: GICombineRule<
(defs root:$dst),
(match (unary_undef_to_zero_frags $dst)),
- (apply [{ Helper.replaceInstWithConstant(*${dst}.getParent(), 0); }])>;
+ (apply (GIReplaceRegWithConstant $dst, 0))>;
def unary_undef_to_undef_frags : unary_undef_frag<
[G_TRUNC, G_BITCAST, G_ANYEXT, G_PTRTOINT, G_INTTOPTR, G_FPTOSI, G_FPTOUI]>;
@@ -889,7 +921,7 @@ class itof_const_zero_fold_rule<Instruction opcode> : GICombineRule <
(match (opcode $dst, 0)),
// Can't use COPY $dst, 0 here because the 0 operand may be a smaller type
// than the destination for itofp.
- (apply [{ Helper.replaceInstWithFConstant(*${dst}.getParent(), 0.0); }])
+ (apply (GIReplaceRegWithFConstant $dst, 0))
>;
def itof_const_zero_fold_si : itof_const_zero_fold_rule<G_SITOFP>;
def itof_const_zero_fold_ui : itof_const_zero_fold_rule<G_UITOFP>;
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-binop-undef-left-to-zero.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-binop-undef-left-to-zero.mir
index b64ac71ef5806..ca77c8fbf5bc7 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-binop-undef-left-to-zero.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-binop-undef-left-to-zero.mir
@@ -39,8 +39,8 @@ body: |
; CHECK-LABEL: name: udiv_scalar
; CHECK: liveins: $w0
; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: %op:_(i32) = G_CONSTANT i32 0
- ; CHECK-NEXT: $w0 = COPY %op(i32)
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: $w0 = COPY [[C]](i32)
%rhs:_(i32) = COPY $w0
%undef:_(i32) = G_IMPLICIT_DEF
%op:_(i32) = G_UDIV %undef(i32), %rhs(i32)
@@ -55,8 +55,8 @@ body: |
; CHECK: liveins: $d0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 0
- ; CHECK-NEXT: %op:_(<2 x i32>) = G_BUILD_VECTOR [[C]](i32), [[C]](i32)
- ; CHECK-NEXT: $d0 = COPY %op(<2 x i32>)
+ ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x i32>) = G_BUILD_VECTOR [[C]](i32), [[C]](i32)
+ ; CHECK-NEXT: $d0 = COPY [[BUILD_VECTOR]](<2 x i32>)
%rhs:_(<2 x i32>) = COPY $d0
%undef:_(<2 x i32>) = G_IMPLICIT_DEF
%op:_(<2 x i32>) = G_UDIV %undef(<2 x i32>), %rhs(<2 x i32>)
@@ -70,8 +70,8 @@ body: |
; CHECK-LABEL: name: urem_scalar
; CHECK: liveins: $w0
; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: %op:_(i32) = G_CONSTANT i32 0
- ; CHECK-NEXT: $w0 = COPY %op(i32)
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: $w0 = COPY [[C]](i32)
%rhs:_(i32) = COPY $w0
%undef:_(i32) = G_IMPLICIT_DEF
%op:_(i32) = G_UREM %undef(i32), %rhs(i32)
@@ -86,8 +86,8 @@ body: |
; CHECK: liveins: $d0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 0
- ; CHECK-NEXT: %op:_(<2 x i32>) = G_BUILD_VECTOR [[C]](i32), [[C]](i32)
- ; CHECK-NEXT: $d0 = COPY %op(<2 x i32>)
+ ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x i32>) = G_BUILD_VECTOR [[C]](i32), [[C]](i32)
+ ; CHECK-NEXT: $d0 = COPY [[BUILD_VECTOR]](<2 x i32>)
%rhs:_(<2 x i32>) = COPY $d0
%undef:_(<2 x i32>) = G_IMPLICIT_DEF
%op:_(<2 x i32>) = G_UREM %undef(<2 x i32>), %rhs(<2 x i32>)
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-constant-fold-itofp-zero.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-constant-fold-itofp-zero.mir
index 83d61027c7e22..48e0817a19718 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-constant-fold-itofp-zero.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-constant-fold-itofp-zero.mir
@@ -12,8 +12,8 @@ body: |
; CHECK-LABEL: name: sitofp
; CHECK: liveins: $d0
; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: %res:_(f64) = G_FCONSTANT double 0.000000e+00
- ; CHECK-NEXT: $d0 = COPY %res(f64)
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(f64) = G_FCONSTANT double 0.000000e+00
+ ; CHECK-NEXT: $d0 = COPY [[C]](f64)
; CHECK-NEXT: RET_ReallyLR implicit $d0
%a:_(i64) = G_CONSTANT i64 0
%res:_(f64) = G_SITOFP %a
@@ -32,8 +32,8 @@ body: |
; CHECK-LABEL: name: uitofp
; CHECK: liveins: $d0
; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: %res:_(f64) = G_FCONSTANT double 0.000000e+00
- ; CHECK-NEXT: $d0 = COPY %res(f64)
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(f64) = G_FCONSTANT double 0.000000e+00
+ ; CHECK-NEXT: $d0 = COPY [[C]](f64)
; CHECK-NEXT: RET_ReallyLR implicit $d0
%a:_(i64) = G_CONSTANT i64 0
%res:_(f64) = G_UITOFP %a
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-replacereg-fconstant-widths.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-replacereg-fconstant-widths.mir
new file mode 100644
index 0000000000000..16b24c274f9cd
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-replacereg-fconstant-widths.mir
@@ -0,0 +1,208 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple aarch64 -run-pass=aarch64-prelegalizer-combiner -verify-machineinstrs %s -o - | FileCheck %s
+
+# Exercises GIReplaceRegWithFConstant (via the itof_const_zero_fold_* and
+# undef_to_fp_zero combine rules) across scalar and vector float widths, to
+# make sure the runtime GIR_BuildFConstant handler reconstructs the correct
+# IEEE bit pattern (and splat, for fixed vectors) for each destination type.
+
+---
+name: uitofp_zero_f16
+liveins:
+ - { reg: '$h0' }
+body: |
+ bb.1.entry:
+ liveins: $h0
+
+ ; CHECK-LABEL: name: uitofp_zero_f16
+ ; CHECK: liveins: $h0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(f16) = G_FCONSTANT half 0.000000e+00
+ ; CHECK-NEXT: $h0 = COPY [[C]](f16)
+ ; CHECK-NEXT: RET_ReallyLR implicit $h0
+ %a:_(i32) = G_CONSTANT i32 0
+ %res:_(f16) = G_UITOFP %a
+ $h0 = COPY %res(f16)
+ RET_ReallyLR implicit $h0
+
+...
+---
+name: sitofp_zero_f16
+liveins:
+ - { reg: '$h0' }
+body: |
+ bb.1.entry:
+ liveins: $h0
+
+ ; CHECK-LABEL: name: sitofp_zero_f16
+ ; CHECK: liveins: $h0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(f16) = G_FCONSTANT half 0.000000e+00
+ ; CHECK-NEXT: $h0 = COPY [[C]](f16)
+ ; CHECK-NEXT: RET_ReallyLR implicit $h0
+ %a:_(i32) = G_CONSTANT i32 0
+ %res:_(f16) = G_SITOFP %a
+ $h0 = COPY %res(f16)
+ RET_ReallyLR implicit $h0
+
+...
+---
+name: uitofp_zero_f32
+liveins:
+ - { reg: '$s0' }
+body: |
+ bb.1.entry:
+ liveins: $s0
+
+ ; CHECK-LABEL: name: uitofp_zero_f32
+ ; CHECK: liveins: $s0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(f32) = G_FCONSTANT float 0.000000e+00
+ ; CHECK-NEXT: $s0 = COPY [[C]](f32)
+ ; CHECK-NEXT: RET_ReallyLR implicit $s0
+ %a:_(i32) = G_CONSTANT i32 0
+ %res:_(f32) = G_UITOFP %a
+ $s0 = COPY %res(f32)
+ RET_ReallyLR implicit $s0
+
+...
+---
+name: uitofp_zero_f64
+liveins:
+ - { reg: '$d0' }
+body: |
+ bb.1.entry:
+ liveins: $d0
+
+ ; CHECK-LABEL: name: uitofp_zero_f64
+ ; CHECK: liveins: $d0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(f64) = G_FCONSTANT double 0.000000e+00
+ ; CHECK-NEXT: $d0 = COPY [[C]](f64)
+ ; CHECK-NEXT: RET_ReallyLR implicit $d0
+ %a:_(i32) = G_CONSTANT i32 0
+ %res:_(f64) = G_UITOFP %a
+ $d0 = COPY %res(f64)
+ RET_ReallyLR implicit $d0
+
+...
+---
+name: uitofp_zero_f128
+liveins:
+ - { reg: '$q0' }
+body: |
+ bb.1.entry:
+ liveins: $q0
+
+ ; CHECK-LABEL: name: uitofp_zero_f128
+ ; CHECK: liveins: $q0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(f128) = G_FCONSTANT fp128 0.000000e+00
+ ; CHECK-NEXT: $q0 = COPY [[C]](f128)
+ ; CHECK-NEXT: RET_ReallyLR implicit $q0
+ %a:_(i32) = G_CONSTANT i32 0
+ %res:_(f128) = G_UITOFP %a
+ $q0 = COPY %res(f128)
+ RET_ReallyLR implicit $q0
+
+...
+---
+name: undef_uitofp_zero_f16
+alignment: 4
+tracksRegLiveness: true
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: undef_uitofp_zero_f16
+ ; CHECK: [[C:%[0-9]+]]:_(f16) = G_FCONSTANT half 0.000000e+00
+ ; CHECK-NEXT: $h0 = COPY [[C]](f16)
+ ; CHECK-NEXT: RET_ReallyLR implicit $h0
+ %0:_(i32) = G_IMPLICIT_DEF
+ %1:_(f16) = G_UITOFP %0(i32)
+ $h0 = COPY %1(f16)
+ RET_ReallyLR implicit $h0
+
+...
+---
+name: undef_sitofp_zero_f64
+alignment: 4
+tracksRegLiveness: true
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: undef_sitofp_zero_f64
+ ; CHECK: [[C:%[0-9]+]]:_(f64) = G_FCONSTANT double 0.000000e+00
+ ; CHECK-NEXT: $d0 = COPY [[C]](f64)
+ ; CHECK-NEXT: RET_ReallyLR implicit $d0
+ %0:_(i32) = G_IMPLICIT_DEF
+ %1:_(f64) = G_SITOFP %0(i32)
+ $d0 = COPY %1(f64)
+ RET_ReallyLR implicit $d0
+
+...
+---
+name: undef_uitofp_zero_v2f32
+alignment: 4
+tracksRegLiveness: true
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: undef_uitofp_zero_v2f32
+ ; CHECK: [[C:%[0-9]+]]:_(f32) = G_FCONSTANT float 0.000000e+00
+ ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x f32>) = G_BUILD_VECTOR [[C]](f32), [[C]](f32)
+ ; CHECK-NEXT: $d0 = COPY [[BUILD_VECTOR]](<2 x f32>)
+ ; CHECK-NEXT: RET_ReallyLR implicit $d0
+ %0:_(<2 x i32>) = G_IMPLICIT_DEF
+ %1:_(<2 x f32>) = G_UITOFP %0(<2 x i32>)
+ $d0 = COPY %1(<2 x f32>)
+ RET_ReallyLR implicit $d0
+
+...
+---
+name: undef_sitofp_zero_v4f32
+alignment: 4
+tracksRegLiveness: true
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: undef_sitofp_zero_v4f32
+ ; CHECK: [[C:%[0-9]+]]:_(f32) = G_FCONSTANT float 0.000000e+00
+ ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<4 x f32>) = G_BUILD_VECTOR [[C]](f32), [[C]](f32), [[C]](f32), [[C]](f32)
+ ; CHECK-NEXT: $q0 = COPY [[BUILD_VECTOR]](<4 x f32>)
+ ; CHECK-NEXT: RET_ReallyLR implicit $q0
+ %0:_(<4 x i32>) = G_IMPLICIT_DEF
+ %1:_(<4 x f32>) = G_SITOFP %0(<4 x i32>)
+ $q0 = COPY %1(<4 x f32>)
+ RET_ReallyLR implicit $q0
+
+...
+---
+name: undef_uitofp_zero_v4f16
+alignment: 4
+tracksRegLiveness: true
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: undef_uitofp_zero_v4f16
+ ; CHECK: [[C:%[0-9]+]]:_(f16) = G_FCONSTANT half 0.000000e+00
+ ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<4 x f16>) = G_BUILD_VECTOR [[C]](f16), [[C]](f16), [[C]](f16), [[C]](f16)
+ ; CHECK-NEXT: $d0 = COPY [[BUILD_VECTOR]](<4 x f16>)
+ ; CHECK-NEXT: RET_ReallyLR implicit $d0
+ %0:_(<4 x i16>) = G_IMPLICIT_DEF
+ %1:_(<4 x f16>) = G_UITOFP %0(<4 x i16>)
+ $d0 = COPY %1(<4 x f16>)
+ RET_ReallyLR implicit $d0
+
+...
+---
+name: undef_uitofp_zero_v2f64
+alignment: 4
+tracksRegLiveness: true
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: undef_uitofp_zero_v2f64
+ ; CHECK: [[C:%[0-9]+]]:_(f64) = G_FCONSTANT double 0.000000e+00
+ ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x f64>) = G_BUILD_VECTOR [[C]](f64), [[C]](f64)
+ ; CHECK-NEXT: $q0 = COPY [[BUILD_VECTOR]](<2 x f64>)
+ ; CHECK-NEXT: RET_ReallyLR implicit $q0
+ %0:_(<2 x i64>) = G_IMPLICIT_DEF
+ %1:_(<2 x f64>) = G_UITOFP %0(<2 x i64>)
+ $q0 = COPY %1(<2 x f64>)
+ RET_ReallyLR implicit $q0
+
+...
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-unary-undef-to-zero.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-unary-undef-to-zero.mir
index 12eb1d5625000..c042d8d3c48cd 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-unary-undef-to-zero.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-unary-undef-to-zero.mir
@@ -13,8 +13,8 @@ body: |
; CHECK-LABEL: name: abs_scalar
; CHECK: liveins: $w0
; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: %abs:_(i32) = G_CONSTANT i32 0
- ; CHECK-NEXT: $w0 = COPY %abs(i32)
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 0
+ ; CHECK-NEXT: $w0 = COPY [[C]](i32)
; CHECK-NEXT: RET_ReallyLR implicit $w0
%undef:_(i32) = G_IMPLICIT_DEF
%abs:_(i32) = G_ABS %undef
@@ -31,8 +31,8 @@ body: |
; CHECK: liveins: $d0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: [[C:%[0-9]+]]:_(i32) = G_CONSTANT i32 0
- ; CHECK-NEXT: %abs:_(<2 x i32>) = G_BUILD_VECTOR [[C]](i32), [[C]](i32)
- ; CHECK-NEXT: $d0 = COPY %abs(<2 x i32>)
+ ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x i32>) = G_BUILD_VECTOR [[C]](i32), [[C]](i32)
+ ; CHECK-NEXT: $d0 = COPY [[BUILD_VECTOR]](<2 x i32>)
; CHECK-NEXT: RET_ReallyLR implicit $d0
%undef:_(<2 x i32>) = G_IMPLICIT_DEF
%abs:_(<2 x i32>) = G_ABS %undef
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-hoist-same-hands.mir b/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-hoist-same-hands.mir
index c054e1a75d024..6dbab62c3c9c8 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-hoist-same-hands.mir
+++ b/llvm/test/CodeGen/A...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/222298
More information about the llvm-commits
mailing list