Skip to content

Commit 795096f

Browse files
author
Martien de Jong
committed
[AIE] Supply vector implementation for FMUL widened from S16
This is a combine pattern that pushes S32 FNEGs through FPEXT These FNEGs prevent standard InstrCombines, and appear in some kernels.
1 parent febb19c commit 795096f

File tree

5 files changed

+259
-6
lines changed

5 files changed

+259
-6
lines changed

llvm/lib/Target/AIE/AIECombine.td

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,12 @@ def combine_narrow_zext_s20 : GICombineRule<
195195
[{ return matchNarrowZext(*${root}, MRI, Observer, ${matchinfo}); }]),
196196
(apply [{ Helper.applyBuildFnNoErase(*${root}, ${matchinfo}); }])>;
197197

198+
def combine_widen_fmul : GICombineRule<
199+
(defs root:$root, build_fn_matchinfo:$matchinfo),
200+
(match (wip_match_opcode G_FMUL): $root,
201+
[{ return matchWidenFMul(*${root}, MRI, Observer, ${matchinfo}); }]),
202+
(apply [{ Helper.applyBuildFn(*${root}, ${matchinfo}); }])>;
203+
198204
def concat_unmerge_matchdata : GIDefMatchData<"AIEConcatUnmergeCombineMatchData">;
199205
def combine_concat_unmerge_phis : GICombineRule <
200206
(defs root:$root, concat_unmerge_matchdata:$matchinfo),
@@ -299,6 +305,7 @@ def aie2p_additional_combines : GICombineGroup<[
299305
combine_vector_shuffle_to_extract_insert_elt,
300306
combine_vector_shuffle_concat_extracted_subvectors,
301307
combine_paired_extracts,
308+
combine_widen_fmul,
302309
combine_vector_shuffle_to_extract_insert_elt_to_broadcast,
303310
combine_bitcast_unmerge_swap,
304311
combine_phi_bitcast_swap

llvm/lib/Target/AIE/AIECombinerHelper.cpp

Lines changed: 100 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,16 @@ cl::opt<bool> MemsetOptimizations(
6868

6969
namespace {
7070

71+
static constexpr const LLT S8 = LLT::scalar(8);
72+
static constexpr const LLT S16 = LLT::scalar(16);
73+
static constexpr const LLT S32 = LLT::scalar(32);
74+
static constexpr const LLT V32S16 = LLT::fixed_vector(32, 16);
75+
static constexpr const LLT V32S32 = LLT::fixed_vector(32, 32);
76+
77+
const llvm::AIEBaseInstrInfo &getAIETII(MachineIRBuilder &B) {
78+
return static_cast<const AIEBaseInstrInfo &>(B.getTII());
79+
}
80+
7181
bool isGenericExtractOpcode(unsigned Opc, const AIEBaseInstrInfo &TII) {
7282
// Check if it's either SEXT or ZEXT extract
7383
const unsigned ExtractSextOpc = TII.getGenericExtractVectorEltOpcode(true);
@@ -78,10 +88,22 @@ bool isGenericExtractOpcode(unsigned Opc, const AIEBaseInstrInfo &TII) {
7888
return Opc == ExtractZextOpc;
7989
}
8090

81-
} // namespace
91+
Register buildScalarAsVector(MachineIRBuilder &B, Register Src, LLT VecTy) {
92+
auto *MRI = B.getMRI();
93+
if (MRI->getType(Src) != S32) {
94+
Src = B.buildAnyExt(S32, Src).getReg(0);
95+
}
96+
const AIEBaseInstrInfo &TII = getAIETII(B);
97+
const Register IdxReg = B.buildConstant(S32, 0).getReg(0);
98+
const Register UndefVec = B.buildUndef(VecTy).getReg(0);
99+
const unsigned InsertEltOpc = TII.getGenericInsertVectorEltOpcode();
100+
Register Vector =
101+
B.buildInstr(InsertEltOpc, {VecTy}, {UndefVec, Src, IdxReg}).getReg(0);
102+
103+
return Vector;
104+
}
82105

83-
static unsigned getNumMaskUndefs(const ArrayRef<int> &Mask,
84-
unsigned StartIndex) {
106+
unsigned getNumMaskUndefs(const ArrayRef<int> &Mask, unsigned StartIndex) {
85107
unsigned Count = 0;
86108
for (unsigned I = StartIndex; I < Mask.size(); ++I) {
87109
if (Mask[I] == -1) {
@@ -91,6 +113,8 @@ static unsigned getNumMaskUndefs(const ArrayRef<int> &Mask,
91113
return Count;
92114
}
93115

116+
} // namespace
117+
94118
bool MaskMatch::isValidMask(const ArrayRef<int> Mask) const {
95119
for (unsigned Idx = 0; Idx < Mask.size(); ++Idx) {
96120
if (Mask[Idx] == -1)
@@ -1069,8 +1093,6 @@ bool llvm::matchExtractVecEltAndExt(
10691093
assert(MI.getOpcode() == TargetOpcode::G_EXTRACT_VECTOR_ELT &&
10701094
"Expected a extract_vector_elt");
10711095
Register DstReg = MI.getOperand(0).getReg();
1072-
const LLT S8 = LLT::scalar(8);
1073-
const LLT S16 = LLT::scalar(16);
10741096
LLT SrcVecTy = MRI.getType(MI.getOperand(1).getReg());
10751097
// Extracts from vectors <= 64-bits are lowered to bit-arithmetic in
10761098
// legalization
@@ -3534,6 +3556,79 @@ bool llvm::matchNarrowZext(MachineInstr &MI, MachineRegisterInfo &MRI,
35343556
return false;
35353557
}
35363558

3559+
namespace {
3560+
// We match widenings from 16 bit, with possible negations on top.
3561+
// Negations commute with conversions and multiplications. We keep track of the
3562+
// total number of negations modulo two.
3563+
class ExtendOperand {
3564+
public:
3565+
Register Source{};
3566+
bool Negate = false;
3567+
ExtendOperand operator-() { return {Source, !Negate}; }
3568+
operator bool() { return Source; }
3569+
};
3570+
3571+
ExtendOperand matchExtend(Register SrcReg, MachineRegisterInfo &MRI) {
3572+
const MachineInstr *SrcMI = MRI.getVRegDef(SrcReg);
3573+
if (SrcMI->getOpcode() == TargetOpcode::G_FPEXT) {
3574+
const Register HalfOp = SrcMI->getOperand(1).getReg();
3575+
if (MRI.getType(HalfOp) != S16) {
3576+
return {};
3577+
}
3578+
return {HalfOp, false};
3579+
}
3580+
if (SrcMI->getOpcode() == TargetOpcode::G_FNEG) {
3581+
return -matchExtend(SrcMI->getOperand(1).getReg(), MRI);
3582+
}
3583+
return {};
3584+
}
3585+
} // namespace
3586+
3587+
bool llvm::matchWidenFMul(MachineInstr &FMul, MachineRegisterInfo &MRI,
3588+
GISelChangeObserver &Observer, BuildFnTy &MatchInfo) {
3589+
if (!FMul.getMF()->getTarget().getTargetTriple().isAIE2P()) {
3590+
return false;
3591+
}
3592+
3593+
ExtendOperand Lft = matchExtend(FMul.getOperand(1).getReg(), MRI);
3594+
if (!Lft) {
3595+
return false;
3596+
}
3597+
ExtendOperand Rgt = matchExtend(FMul.getOperand(2).getReg(), MRI);
3598+
if (!Rgt) {
3599+
return false;
3600+
}
3601+
3602+
const Register DstReg = FMul.getOperand(0).getReg();
3603+
const bool Negate = Lft.Negate ^ Rgt.Negate;
3604+
3605+
// We build extract(mul(tovector(Lft), tovector(Rgt), 0);
3606+
MatchInfo = [=, &MRI](MachineIRBuilder &B) {
3607+
auto &TII = getAIETII(B);
3608+
Register LSrc = Lft.Source;
3609+
if (Negate) {
3610+
LSrc = MRI.createGenericVirtualRegister(S16);
3611+
B.buildInstr(TargetOpcode::G_FNEG, {LSrc}, {Lft.Source});
3612+
}
3613+
const LLT VecTy = V32S16;
3614+
const LLT AccTy = V32S32;
3615+
const Register VLhs = buildScalarAsVector(B, LSrc, VecTy);
3616+
const Register VRhs = buildScalarAsVector(B, Rgt.Source, VecTy);
3617+
const Register Acc = MRI.createGenericVirtualRegister(AccTy);
3618+
const Register Mode = B.buildConstant(S32, 60).getReg(0);
3619+
B.buildIntrinsic(Intrinsic::aie2p_I512_I512_ACC1024_bf_mul_conf, Acc, true,
3620+
false)
3621+
.addUse(VLhs)
3622+
.addUse(VRhs)
3623+
.addUse(Mode);
3624+
const Register Index = B.buildConstant(S32, 0).getReg(0);
3625+
B.buildInstr(TII.getGenericExtractVectorEltOpcode(/*SignExt*/ true),
3626+
{DstReg}, {Acc, Index});
3627+
};
3628+
3629+
return true;
3630+
}
3631+
35373632
// Fold G_TRUNC (G_[ANY|S|Z]EXT x) -> X or (G_[ANY|S|Z]EXT x) or (G_TRUNC x).
35383633
bool llvm::matchCombineExtAndTrunc(MachineInstr &MI, MachineRegisterInfo &MRI,
35393634
BuildFnTy &MatchInfo) {

llvm/lib/Target/AIE/AIECombinerHelper.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,9 @@ bool matchNarrowTruncConstant(MachineInstr &MI, MachineRegisterInfo &MRI,
272272
bool matchNarrowZext(MachineInstr &MI, MachineRegisterInfo &MRI,
273273
GISelChangeObserver &Observer, BuildFnTy &MatchInfo);
274274

275+
bool matchWidenFMul(MachineInstr &MI, MachineRegisterInfo &MRI,
276+
GISelChangeObserver &Observer, BuildFnTy &MatchInfo);
277+
275278
bool matchCombineExtAndTrunc(MachineInstr &MI, MachineRegisterInfo &MRI,
276279
BuildFnTy &MatchInfo);
277280

llvm/lib/Target/AIE/AIELegalizerHelper.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1405,7 +1405,7 @@ bool AIELegalizerHelper::legalizeG_FMUL(LegalizerHelper &Helper,
14051405
MachineRegisterInfo &MRI = *MIRBuilder.getMRI();
14061406

14071407
const Register DstReg = MI.getOperand(0).getReg();
1408-
assert(MRI.getType(DstReg) == LLT::scalar(16) &&
1408+
assert(MRI.getType(DstReg) == S16 &&
14091409
"Expected bfloat16 type in custom legalization.");
14101410

14111411
Register SrcLHS = MI.getOperand(1).getReg();
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 4
2+
# This file is licensed under the Apache License v2.0 with LLVM Exceptions.
3+
# See https://llvm.org/LICENSE.txt for license information.
4+
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5+
#
6+
# (c) Copyright 2025 Advanced Micro Devices, Inc. or its affiliates
7+
8+
# RUN: llc -mtriple aie2p -run-pass=aie2p-prelegalizer-combiner %s -verify-machineinstrs -o - | FileCheck %s
9+
10+
---
11+
name: test_widened_fmul_s16
12+
body: |
13+
bb.0:
14+
liveins: $r1, $r2, $p0
15+
; CHECK-LABEL: name: test_widened_fmul_s16
16+
; CHECK: liveins: $r1, $r2, $p0
17+
; CHECK-NEXT: {{ $}}
18+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $r1
19+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $r2
20+
; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
21+
; CHECK-NEXT: [[DEF:%[0-9]+]]:_(<32 x s16>) = G_IMPLICIT_DEF
22+
; CHECK-NEXT: [[AIE_INSERT_VECTOR_ELT:%[0-9]+]]:_(<32 x s16>) = G_AIE_INSERT_VECTOR_ELT [[DEF]], [[COPY]](s32), [[C]](s32)
23+
; CHECK-NEXT: [[AIE_INSERT_VECTOR_ELT1:%[0-9]+]]:_(<32 x s16>) = G_AIE_INSERT_VECTOR_ELT [[DEF]], [[COPY1]](s32), [[C]](s32)
24+
; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 60
25+
; CHECK-NEXT: [[INT:%[0-9]+]]:_(<32 x s32>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aie2p.I512.I512.ACC1024.bf.mul.conf), [[AIE_INSERT_VECTOR_ELT]](<32 x s16>), [[AIE_INSERT_VECTOR_ELT1]](<32 x s16>), [[C1]](s32)
26+
; CHECK-NEXT: [[UV:%[0-9]+]]:_(<16 x s32>), [[UV1:%[0-9]+]]:_(<16 x s32>) = G_UNMERGE_VALUES [[INT]](<32 x s32>)
27+
; CHECK-NEXT: [[AIE_SEXT_EXTRACT_VECTOR_ELT:%[0-9]+]]:_(s32) = G_AIE_SEXT_EXTRACT_VECTOR_ELT [[UV]](<16 x s32>), [[C]](s32)
28+
; CHECK-NEXT: $r0 = COPY [[AIE_SEXT_EXTRACT_VECTOR_ELT]](s32)
29+
; CHECK-NEXT: PseudoRET implicit $lr, implicit $r0
30+
%0:_(s32) = COPY $r1
31+
%1:_(s32) = COPY $r2
32+
%2:_(s16) = G_TRUNC %0(s32)
33+
%3:_(s16) = G_TRUNC %1(s32)
34+
%4:_(s32) = G_FPEXT %2(s16)
35+
%5:_(s32) = G_FPEXT %3(s16)
36+
%6:_(s32) = G_FMUL %4, %5
37+
$r0 = COPY %6(s32)
38+
PseudoRET implicit $lr, implicit $r0
39+
...
40+
41+
---
42+
name: test_widened_fmul_negl_s16
43+
body: |
44+
bb.0:
45+
liveins: $r1, $r2, $p0
46+
; CHECK-LABEL: name: test_widened_fmul_negl_s16
47+
; CHECK: liveins: $r1, $r2, $p0
48+
; CHECK-NEXT: {{ $}}
49+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $r1
50+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $r2
51+
; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s32)
52+
; CHECK-NEXT: [[FNEG:%[0-9]+]]:_(s16) = G_FNEG [[TRUNC]]
53+
; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[FNEG]](s16)
54+
; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
55+
; CHECK-NEXT: [[DEF:%[0-9]+]]:_(<32 x s16>) = G_IMPLICIT_DEF
56+
; CHECK-NEXT: [[AIE_INSERT_VECTOR_ELT:%[0-9]+]]:_(<32 x s16>) = G_AIE_INSERT_VECTOR_ELT [[DEF]], [[ANYEXT]](s32), [[C]](s32)
57+
; CHECK-NEXT: [[AIE_INSERT_VECTOR_ELT1:%[0-9]+]]:_(<32 x s16>) = G_AIE_INSERT_VECTOR_ELT [[DEF]], [[COPY1]](s32), [[C]](s32)
58+
; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 60
59+
; CHECK-NEXT: [[INT:%[0-9]+]]:_(<32 x s32>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aie2p.I512.I512.ACC1024.bf.mul.conf), [[AIE_INSERT_VECTOR_ELT]](<32 x s16>), [[AIE_INSERT_VECTOR_ELT1]](<32 x s16>), [[C1]](s32)
60+
; CHECK-NEXT: [[UV:%[0-9]+]]:_(<16 x s32>), [[UV1:%[0-9]+]]:_(<16 x s32>) = G_UNMERGE_VALUES [[INT]](<32 x s32>)
61+
; CHECK-NEXT: [[AIE_SEXT_EXTRACT_VECTOR_ELT:%[0-9]+]]:_(s32) = G_AIE_SEXT_EXTRACT_VECTOR_ELT [[UV]](<16 x s32>), [[C]](s32)
62+
; CHECK-NEXT: $r0 = COPY [[AIE_SEXT_EXTRACT_VECTOR_ELT]](s32)
63+
; CHECK-NEXT: PseudoRET implicit $lr, implicit $r0
64+
%0:_(s32) = COPY $r1
65+
%1:_(s32) = COPY $r2
66+
%2:_(s16) = G_TRUNC %0(s32)
67+
%3:_(s16) = G_TRUNC %1(s32)
68+
%4:_(s32) = G_FPEXT %2(s16)
69+
%5:_(s32) = G_FPEXT %3(s16)
70+
%6:_(s32) = G_FNEG %4(s32)
71+
%8:_(s32) = G_FMUL %6, %5
72+
$r0 = COPY %8(s32)
73+
PseudoRET implicit $lr, implicit $r0
74+
...
75+
---
76+
name: test_widened_fmul_negr_s16
77+
body: |
78+
bb.0:
79+
liveins: $r1, $r2, $p0
80+
; CHECK-LABEL: name: test_widened_fmul_negr_s16
81+
; CHECK: liveins: $r1, $r2, $p0
82+
; CHECK-NEXT: {{ $}}
83+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $r1
84+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $r2
85+
; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s32)
86+
; CHECK-NEXT: [[FNEG:%[0-9]+]]:_(s16) = G_FNEG [[TRUNC]]
87+
; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[FNEG]](s16)
88+
; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
89+
; CHECK-NEXT: [[DEF:%[0-9]+]]:_(<32 x s16>) = G_IMPLICIT_DEF
90+
; CHECK-NEXT: [[AIE_INSERT_VECTOR_ELT:%[0-9]+]]:_(<32 x s16>) = G_AIE_INSERT_VECTOR_ELT [[DEF]], [[ANYEXT]](s32), [[C]](s32)
91+
; CHECK-NEXT: [[AIE_INSERT_VECTOR_ELT1:%[0-9]+]]:_(<32 x s16>) = G_AIE_INSERT_VECTOR_ELT [[DEF]], [[COPY1]](s32), [[C]](s32)
92+
; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 60
93+
; CHECK-NEXT: [[INT:%[0-9]+]]:_(<32 x s32>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aie2p.I512.I512.ACC1024.bf.mul.conf), [[AIE_INSERT_VECTOR_ELT]](<32 x s16>), [[AIE_INSERT_VECTOR_ELT1]](<32 x s16>), [[C1]](s32)
94+
; CHECK-NEXT: [[UV:%[0-9]+]]:_(<16 x s32>), [[UV1:%[0-9]+]]:_(<16 x s32>) = G_UNMERGE_VALUES [[INT]](<32 x s32>)
95+
; CHECK-NEXT: [[AIE_SEXT_EXTRACT_VECTOR_ELT:%[0-9]+]]:_(s32) = G_AIE_SEXT_EXTRACT_VECTOR_ELT [[UV]](<16 x s32>), [[C]](s32)
96+
; CHECK-NEXT: $r0 = COPY [[AIE_SEXT_EXTRACT_VECTOR_ELT]](s32)
97+
; CHECK-NEXT: PseudoRET implicit $lr, implicit $r0
98+
%0:_(s32) = COPY $r1
99+
%1:_(s32) = COPY $r2
100+
%2:_(s16) = G_TRUNC %0(s32)
101+
%3:_(s16) = G_TRUNC %1(s32)
102+
%4:_(s32) = G_FPEXT %2(s16)
103+
%5:_(s32) = G_FPEXT %3(s16)
104+
%6:_(s32) = G_FNEG %5(s32)
105+
%8:_(s32) = G_FMUL %4, %6
106+
$r0 = COPY %8(s32)
107+
PseudoRET implicit $lr, implicit $r0
108+
...
109+
---
110+
name: test_widened_fmul_negboth_s16
111+
body: |
112+
bb.0:
113+
liveins: $r1, $r2, $p0
114+
; CHECK-LABEL: name: test_widened_fmul_negboth_s16
115+
; CHECK: liveins: $r1, $r2, $p0
116+
; CHECK-NEXT: {{ $}}
117+
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $r1
118+
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $r2
119+
; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
120+
; CHECK-NEXT: [[DEF:%[0-9]+]]:_(<32 x s16>) = G_IMPLICIT_DEF
121+
; CHECK-NEXT: [[AIE_INSERT_VECTOR_ELT:%[0-9]+]]:_(<32 x s16>) = G_AIE_INSERT_VECTOR_ELT [[DEF]], [[COPY]](s32), [[C]](s32)
122+
; CHECK-NEXT: [[AIE_INSERT_VECTOR_ELT1:%[0-9]+]]:_(<32 x s16>) = G_AIE_INSERT_VECTOR_ELT [[DEF]], [[COPY1]](s32), [[C]](s32)
123+
; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 60
124+
; CHECK-NEXT: [[INT:%[0-9]+]]:_(<32 x s32>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aie2p.I512.I512.ACC1024.bf.mul.conf), [[AIE_INSERT_VECTOR_ELT]](<32 x s16>), [[AIE_INSERT_VECTOR_ELT1]](<32 x s16>), [[C1]](s32)
125+
; CHECK-NEXT: [[UV:%[0-9]+]]:_(<16 x s32>), [[UV1:%[0-9]+]]:_(<16 x s32>) = G_UNMERGE_VALUES [[INT]](<32 x s32>)
126+
; CHECK-NEXT: [[AIE_SEXT_EXTRACT_VECTOR_ELT:%[0-9]+]]:_(s32) = G_AIE_SEXT_EXTRACT_VECTOR_ELT [[UV]](<16 x s32>), [[C]](s32)
127+
; CHECK-NEXT: $r0 = COPY [[AIE_SEXT_EXTRACT_VECTOR_ELT]](s32)
128+
; CHECK-NEXT: PseudoRET implicit $lr, implicit $r0
129+
%0:_(s32) = COPY $r1
130+
%1:_(s32) = COPY $r2
131+
%2:_(s16) = G_TRUNC %0(s32)
132+
%3:_(s16) = G_TRUNC %1(s32)
133+
%4:_(s32) = G_FPEXT %2(s16)
134+
%5:_(s32) = G_FPEXT %3(s16)
135+
%6:_(s32) = G_FNEG %4(s32)
136+
%7:_(s32) = G_FNEG %5(s32)
137+
%8:_(s32) = G_FMUL %6, %7
138+
$r0 = COPY %8(s32)
139+
PseudoRET implicit $lr, implicit $r0
140+
...
141+
142+
143+
144+
145+
146+
147+
148+

0 commit comments

Comments
 (0)