Skip to content

Commit 6b7bb51

Browse files
author
v01dxyz
committed
[CodeGen] Legalisation with promotion: optimise count leading ones
(CTLZ (XOR Op -1)) --> (CTLZ_ZERO_UNDEF (XOR (SHIFT (ANYEXTEND Op) ShiftAmount) -1)) The optimisation also applies for CTLZ_ZERO_UNDEF, VP_CTLZ, VP_CTLZ_ZERO_UNDEF. Fixes #96455
1 parent 4d5edeb commit 6b7bb51

File tree

7 files changed

+274
-31
lines changed

7 files changed

+274
-31
lines changed

Diff for: llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp

+26
Original file line numberDiff line numberDiff line change
@@ -2356,6 +2356,25 @@ LegalizerHelper::widenScalarMulo(MachineInstr &MI, unsigned TypeIdx,
23562356
return Legalized;
23572357
}
23582358

2359+
static bool extendCtlzNot(const MachineInstr &MI, MachineIRBuilder &MIRBuilder,
2360+
MachineRegisterInfo &MRI, LLT WideTy) {
2361+
Register Src;
2362+
if (!mi_match(MI.getOperand(1).getReg(), MRI, m_Not(m_Reg(Src))))
2363+
return false;
2364+
2365+
auto ExtSrc = MIRBuilder.buildAnyExt(WideTy, Src);
2366+
2367+
Register SrcReg = MI.getOperand(1).getReg();
2368+
LLT CurTy = MRI.getType(SrcReg);
2369+
unsigned SizeDiff = WideTy.getSizeInBits() - CurTy.getSizeInBits();
2370+
auto LShift = MIRBuilder.buildShl(WideTy, ExtSrc,
2371+
MIRBuilder.buildConstant(WideTy, SizeDiff));
2372+
auto Not = MIRBuilder.buildNot(WideTy, LShift);
2373+
MIRBuilder.buildCTLZ_ZERO_UNDEF(MI.getOperand(0), Not);
2374+
2375+
return true;
2376+
}
2377+
23592378
LegalizerHelper::LegalizeResult
23602379
LegalizerHelper::widenScalar(MachineInstr &MI, unsigned TypeIdx, LLT WideTy) {
23612380
switch (MI.getOpcode()) {
@@ -2449,6 +2468,13 @@ LegalizerHelper::widenScalar(MachineInstr &MI, unsigned TypeIdx, LLT WideTy) {
24492468
auto MIBSrc = MIRBuilder.buildInstr(ExtOpc, {WideTy}, {SrcReg});
24502469
LLT CurTy = MRI.getType(SrcReg);
24512470
unsigned NewOpc = MI.getOpcode();
2471+
2472+
if ((MI.getOpcode() == TargetOpcode::G_CTLZ ||
2473+
MI.getOpcode() == TargetOpcode::G_CTLZ_ZERO_UNDEF) &&
2474+
extendCtlzNot(MI, MIRBuilder, MRI, WideTy)) {
2475+
MI.eraseFromParent();
2476+
return Legalized;
2477+
}
24522478
if (NewOpc == TargetOpcode::G_CTTZ) {
24532479
// The count is the same in the larger type except if the original
24542480
// value was zero. This can be handled by setting the bit just off

Diff for: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp

+34
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "llvm/CodeGen/MachineJumpTableInfo.h"
2727
#include "llvm/CodeGen/MachineMemOperand.h"
2828
#include "llvm/CodeGen/RuntimeLibcalls.h"
29+
#include "llvm/CodeGen/SDPatternMatch.h"
2930
#include "llvm/CodeGen/SelectionDAG.h"
3031
#include "llvm/CodeGen/SelectionDAGNodes.h"
3132
#include "llvm/CodeGen/TargetFrameLowering.h"
@@ -54,6 +55,7 @@
5455
#include <utility>
5556

5657
using namespace llvm;
58+
using namespace llvm::SDPatternMatch;
5759

5860
#define DEBUG_TYPE "legalizedag"
5961

@@ -5049,6 +5051,27 @@ static MVT getPromotedVectorElementType(const TargetLowering &TLI,
50495051
return MidVT;
50505052
}
50515053

5054+
// (CTLZ (XOR Op -1)) --> (TRUNCATE (CTLZ_ZERO_UNDEF
5055+
// (XOR (SHIFT (ANYEXTEND Op1)
5056+
// ShiftAmount)
5057+
// -1)))
5058+
static bool ExtendCtlzNot(SDNode *Node, SDValue &Result, SDLoc &dl, MVT OVT,
5059+
MVT NVT, SelectionDAG &DAG) {
5060+
SDValue SrcOp;
5061+
if (!sd_match(Node->getOperand(0), m_Not(m_Value(SrcOp))))
5062+
return false;
5063+
5064+
SDValue ExtSrc = DAG.getNode(ISD::ANY_EXTEND, dl, NVT, SrcOp);
5065+
unsigned SHLAmount = NVT.getScalarSizeInBits() - OVT.getScalarSizeInBits();
5066+
SDValue ShiftConst =
5067+
DAG.getShiftAmountConstant(SHLAmount, ExtSrc.getValueType(), dl);
5068+
SDValue LShift = DAG.getNode(ISD::SHL, dl, NVT, ExtSrc, ShiftConst);
5069+
SDValue Not = DAG.getNOT(dl, LShift, NVT);
5070+
SDValue Ctlz = DAG.getNode(ISD::CTLZ_ZERO_UNDEF, dl, NVT, Not);
5071+
Result = DAG.getNode(ISD::TRUNCATE, dl, OVT, Ctlz);
5072+
return true;
5073+
}
5074+
50525075
void SelectionDAGLegalize::PromoteNode(SDNode *Node) {
50535076
LLVM_DEBUG(dbgs() << "Trying to promote node\n");
50545077
SmallVector<SDValue, 8> Results;
@@ -5084,6 +5107,13 @@ void SelectionDAGLegalize::PromoteNode(SDNode *Node) {
50845107
case ISD::CTTZ_ZERO_UNDEF:
50855108
case ISD::CTLZ:
50865109
case ISD::CTPOP: {
5110+
// If the operand of CTLZ is NOT, push the extend in the NOT.
5111+
if (Node->getOpcode() == ISD::CTLZ &&
5112+
ExtendCtlzNot(Node, Tmp1, dl, OVT, NVT, DAG)) {
5113+
Results.push_back(Tmp1);
5114+
break;
5115+
}
5116+
50875117
// Zero extend the argument unless its cttz, then use any_extend.
50885118
if (Node->getOpcode() == ISD::CTTZ ||
50895119
Node->getOpcode() == ISD::CTTZ_ZERO_UNDEF)
@@ -5115,6 +5145,10 @@ void SelectionDAGLegalize::PromoteNode(SDNode *Node) {
51155145
break;
51165146
}
51175147
case ISD::CTLZ_ZERO_UNDEF: {
5148+
if (ExtendCtlzNot(Node, Tmp1, dl, OVT, NVT, DAG)) {
5149+
Results.push_back(Tmp1);
5150+
break;
5151+
}
51185152
// We know that the argument is unlikely to be zero, hence we can take a
51195153
// different approach as compared to ISD::CTLZ
51205154

Diff for: llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp

+43
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
#include "LegalizeTypes.h"
2121
#include "llvm/Analysis/TargetLibraryInfo.h"
22+
#include "llvm/CodeGen/SDPatternMatch.h"
2223
#include "llvm/CodeGen/StackMaps.h"
2324
#include "llvm/CodeGen/TargetLowering.h"
2425
#include "llvm/IR/DerivedTypes.h"
@@ -27,6 +28,7 @@
2728
#include "llvm/Support/raw_ostream.h"
2829
#include <algorithm>
2930
using namespace llvm;
31+
using namespace llvm::SDPatternMatch;
3032

3133
#define DEBUG_TYPE "legalize-types"
3234

@@ -638,6 +640,39 @@ SDValue DAGTypeLegalizer::PromoteIntRes_Constant(SDNode *N) {
638640
return Result;
639641
}
640642

643+
// (CTLZ (XOR Op -1)) --> (CTLZ_ZERO_UNDEF (XOR (SHIFT (ANYEXTEND Op1)
644+
// ShiftAmount)
645+
// -1))
646+
static bool ExtendCtlzNot(SDNode *Node, SDValue &Result, SDLoc &dl, EVT OVT,
647+
EVT NVT, SelectionDAG &DAG) {
648+
SDValue SrcOp;
649+
if (!sd_match(Node->getOperand(0), m_Not(m_Value(SrcOp))))
650+
return false;
651+
652+
SDValue ExtSrc = DAG.getNode(ISD::ANY_EXTEND, dl, NVT, SrcOp);
653+
unsigned SHLAmount = NVT.getScalarSizeInBits() - OVT.getScalarSizeInBits();
654+
SDValue ShiftConst =
655+
DAG.getShiftAmountConstant(SHLAmount, ExtSrc.getValueType(), dl);
656+
657+
SDValue NCstOp =
658+
DAG.getConstant(APInt::getAllOnes(NVT.getScalarSizeInBits()), dl, NVT);
659+
if (!Node->isVPOpcode()) {
660+
SDValue LShift = DAG.getNode(ISD::SHL, dl, NVT, ExtSrc, ShiftConst);
661+
SDValue Not = DAG.getNOT(dl, LShift, NVT);
662+
Result = DAG.getNode(ISD::CTLZ_ZERO_UNDEF, dl, NVT, Not);
663+
} else {
664+
SDValue Mask = Node->getOperand(1);
665+
SDValue EVL = Node->getOperand(2);
666+
667+
SDValue LShift =
668+
DAG.getNode(ISD::VP_SHL, dl, NVT, ExtSrc, ShiftConst, Mask, EVL);
669+
SDValue Not = DAG.getNode(ISD::VP_XOR, dl, NVT, LShift, NCstOp, Mask, EVL);
670+
Result = DAG.getNode(ISD::VP_CTLZ_ZERO_UNDEF, dl, NVT, Not, Mask, EVL);
671+
}
672+
673+
return true;
674+
}
675+
641676
SDValue DAGTypeLegalizer::PromoteIntRes_CTLZ(SDNode *N) {
642677
EVT OVT = N->getValueType(0);
643678
EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), OVT);
@@ -656,6 +691,14 @@ SDValue DAGTypeLegalizer::PromoteIntRes_CTLZ(SDNode *N) {
656691
}
657692

658693
unsigned CtlzOpcode = N->getOpcode();
694+
// If the operand of CTLZ is NOT, push the extend in the NOT.
695+
if (SDValue Res;
696+
(CtlzOpcode == ISD::CTLZ || CtlzOpcode == ISD::CTLZ_ZERO_UNDEF ||
697+
CtlzOpcode == ISD::VP_CTLZ || CtlzOpcode == ISD::VP_CTLZ_ZERO_UNDEF) &&
698+
ExtendCtlzNot(N, Res, dl, OVT, NVT, DAG)) {
699+
return Res;
700+
}
701+
659702
if (CtlzOpcode == ISD::CTLZ || CtlzOpcode == ISD::VP_CTLZ) {
660703
// Subtract off the extra leading bits in the bigger type.
661704
SDValue ExtractLeadingBits = DAG.getConstant(

Diff for: llvm/test/CodeGen/AArch64/ctlo.ll

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc < %s --mtriple=aarch64 -verify-machineinstrs | FileCheck %s
3+
; RUN: llc < %s --mtriple=aarch64 -global-isel -verify-machineinstrs | FileCheck %s
4+
5+
declare i8 @llvm.ctlz.i8(i8, i1)
6+
declare i16 @llvm.ctlz.i16(i16, i1)
7+
declare i32 @llvm.ctlz.i32(i32, i1)
8+
declare i64 @llvm.ctlz.i64(i64, i1)
9+
10+
define i8 @ctlo_i8(i8 %x) {
11+
; CHECK-LABEL: ctlo_i8:
12+
; CHECK: // %bb.0:
13+
; CHECK-NEXT: mov w8, #-1 // =0xffffffff
14+
; CHECK-NEXT: eor w8, w8, w0, lsl #24
15+
; CHECK-NEXT: clz w0, w8
16+
; CHECK-NEXT: ret
17+
%tmp1 = xor i8 %x, -1
18+
%tmp2 = call i8 @llvm.ctlz.i8( i8 %tmp1, i1 false )
19+
ret i8 %tmp2
20+
}
21+
22+
define i8 @ctlo_i8_undef(i8 %x) {
23+
; CHECK-LABEL: ctlo_i8_undef:
24+
; CHECK: // %bb.0:
25+
; CHECK-NEXT: mov w8, #-1 // =0xffffffff
26+
; CHECK-NEXT: eor w8, w8, w0, lsl #24
27+
; CHECK-NEXT: clz w0, w8
28+
; CHECK-NEXT: ret
29+
%tmp1 = xor i8 %x, -1
30+
%tmp2 = call i8 @llvm.ctlz.i8( i8 %tmp1, i1 true )
31+
ret i8 %tmp2
32+
}
33+
34+
define i16 @ctlo_i16(i16 %x) {
35+
; CHECK-LABEL: ctlo_i16:
36+
; CHECK: // %bb.0:
37+
; CHECK-NEXT: mov w8, #-1 // =0xffffffff
38+
; CHECK-NEXT: eor w8, w8, w0, lsl #16
39+
; CHECK-NEXT: clz w0, w8
40+
; CHECK-NEXT: ret
41+
%tmp1 = xor i16 %x, -1
42+
%tmp2 = call i16 @llvm.ctlz.i16( i16 %tmp1, i1 false )
43+
ret i16 %tmp2
44+
}
45+
46+
define i16 @ctlo_i16_undef(i16 %x) {
47+
; CHECK-LABEL: ctlo_i16_undef:
48+
; CHECK: // %bb.0:
49+
; CHECK-NEXT: mov w8, #-1 // =0xffffffff
50+
; CHECK-NEXT: eor w8, w8, w0, lsl #16
51+
; CHECK-NEXT: clz w0, w8
52+
; CHECK-NEXT: ret
53+
%tmp1 = xor i16 %x, -1
54+
%tmp2 = call i16 @llvm.ctlz.i16( i16 %tmp1, i1 true )
55+
ret i16 %tmp2
56+
}
57+
58+
define i32 @ctlo_i32(i32 %x) {
59+
; CHECK-LABEL: ctlo_i32:
60+
; CHECK: // %bb.0:
61+
; CHECK-NEXT: mvn w8, w0
62+
; CHECK-NEXT: clz w0, w8
63+
; CHECK-NEXT: ret
64+
%tmp1 = xor i32 %x, -1
65+
%tmp2 = call i32 @llvm.ctlz.i32( i32 %tmp1, i1 false )
66+
ret i32 %tmp2
67+
}
68+
69+
define i32 @ctlo_i32_undef(i32 %x) {
70+
; CHECK-LABEL: ctlo_i32_undef:
71+
; CHECK: // %bb.0:
72+
; CHECK-NEXT: mvn w8, w0
73+
; CHECK-NEXT: clz w0, w8
74+
; CHECK-NEXT: ret
75+
%tmp1 = xor i32 %x, -1
76+
%tmp2 = call i32 @llvm.ctlz.i32( i32 %tmp1, i1 true )
77+
ret i32 %tmp2
78+
}
79+
80+
define i64 @ctlo_i64(i64 %x) {
81+
; CHECK-LABEL: ctlo_i64:
82+
; CHECK: // %bb.0:
83+
; CHECK-NEXT: mvn x8, x0
84+
; CHECK-NEXT: clz x0, x8
85+
; CHECK-NEXT: ret
86+
%tmp1 = xor i64 %x, -1
87+
%tmp2 = call i64 @llvm.ctlz.i64( i64 %tmp1, i1 false )
88+
ret i64 %tmp2
89+
}
90+
91+
define i64 @ctlo_i64_undef(i64 %x) {
92+
; CHECK-LABEL: ctlo_i64_undef:
93+
; CHECK: // %bb.0:
94+
; CHECK-NEXT: mvn x8, x0
95+
; CHECK-NEXT: clz x0, x8
96+
; CHECK-NEXT: ret
97+
%tmp1 = xor i64 %x, -1
98+
%tmp2 = call i64 @llvm.ctlz.i64( i64 %tmp1, i1 true )
99+
ret i64 %tmp2
100+
}

Diff for: llvm/test/CodeGen/LoongArch/ctlz-cttz-ctpop.ll

+8-16
Original file line numberDiff line numberDiff line change
@@ -89,18 +89,14 @@ define i64 @test_ctlz_i64(i64 %a) nounwind {
8989
define i8 @test_not_ctlz_i8(i8 %a) nounwind {
9090
; LA32-LABEL: test_not_ctlz_i8:
9191
; LA32: # %bb.0:
92-
; LA32-NEXT: ori $a1, $zero, 255
93-
; LA32-NEXT: andn $a0, $a1, $a0
94-
; LA32-NEXT: clz.w $a0, $a0
95-
; LA32-NEXT: addi.w $a0, $a0, -24
92+
; LA32-NEXT: slli.w $a0, $a0, 24
93+
; LA32-NEXT: clo.w $a0, $a0
9694
; LA32-NEXT: ret
9795
;
9896
; LA64-LABEL: test_not_ctlz_i8:
9997
; LA64: # %bb.0:
100-
; LA64-NEXT: ori $a1, $zero, 255
101-
; LA64-NEXT: andn $a0, $a1, $a0
102-
; LA64-NEXT: clz.d $a0, $a0
103-
; LA64-NEXT: addi.d $a0, $a0, -56
98+
; LA64-NEXT: slli.d $a0, $a0, 56
99+
; LA64-NEXT: clo.d $a0, $a0
104100
; LA64-NEXT: ret
105101
%neg = xor i8 %a, -1
106102
%tmp = call i8 @llvm.ctlz.i8(i8 %neg, i1 false)
@@ -110,18 +106,14 @@ define i8 @test_not_ctlz_i8(i8 %a) nounwind {
110106
define i16 @test_not_ctlz_i16(i16 %a) nounwind {
111107
; LA32-LABEL: test_not_ctlz_i16:
112108
; LA32: # %bb.0:
113-
; LA32-NEXT: nor $a0, $a0, $zero
114-
; LA32-NEXT: bstrpick.w $a0, $a0, 15, 0
115-
; LA32-NEXT: clz.w $a0, $a0
116-
; LA32-NEXT: addi.w $a0, $a0, -16
109+
; LA32-NEXT: slli.w $a0, $a0, 16
110+
; LA32-NEXT: clo.w $a0, $a0
117111
; LA32-NEXT: ret
118112
;
119113
; LA64-LABEL: test_not_ctlz_i16:
120114
; LA64: # %bb.0:
121-
; LA64-NEXT: nor $a0, $a0, $zero
122-
; LA64-NEXT: bstrpick.d $a0, $a0, 15, 0
123-
; LA64-NEXT: clz.d $a0, $a0
124-
; LA64-NEXT: addi.d $a0, $a0, -48
115+
; LA64-NEXT: slli.d $a0, $a0, 48
116+
; LA64-NEXT: clo.d $a0, $a0
125117
; LA64-NEXT: ret
126118
%neg = xor i16 %a, -1
127119
%tmp = call i16 @llvm.ctlz.i16(i16 %neg, i1 false)

Diff for: llvm/test/CodeGen/RISCV/rvv/ctlz-vp.ll

+52
Original file line numberDiff line numberDiff line change
@@ -2624,6 +2624,58 @@ define <vscale x 1 x i9> @vp_ctlz_zero_undef_nxv1i9(<vscale x 1 x i9> %va, <vsca
26242624
%v = call <vscale x 1 x i9> @llvm.vp.ctlz.nxv1i9(<vscale x 1 x i9> %va, i1 true, <vscale x 1 x i1> %m, i32 %evl)
26252625
ret <vscale x 1 x i9> %v
26262626
}
2627+
define <vscale x 1 x i9> @vp_ctlo_nxv1i9(<vscale x 1 x i9> %va, <vscale x 1 x i1> %m, i32 zeroext %evl) {
2628+
; CHECK-LABEL: vp_ctlo_nxv1i9:
2629+
; CHECK: # %bb.0:
2630+
; CHECK-NEXT: vsetvli zero, a0, e16, mf4, ta, ma
2631+
; CHECK-NEXT: vsll.vi v8, v8, 7, v0.t
2632+
; CHECK-NEXT: vnot.v v8, v8, v0.t
2633+
; CHECK-NEXT: vfwcvt.f.xu.v v9, v8, v0.t
2634+
; CHECK-NEXT: vsetvli zero, zero, e32, mf2, ta, ma
2635+
; CHECK-NEXT: vsrl.vi v8, v9, 23, v0.t
2636+
; CHECK-NEXT: vsetvli zero, zero, e16, mf4, ta, ma
2637+
; CHECK-NEXT: vnsrl.wi v8, v8, 0, v0.t
2638+
; CHECK-NEXT: li a0, 142
2639+
; CHECK-NEXT: vrsub.vx v8, v8, a0, v0.t
2640+
; CHECK-NEXT: ret
2641+
;
2642+
; CHECK-ZVBB-LABEL: vp_ctlo_nxv1i9:
2643+
; CHECK-ZVBB: # %bb.0:
2644+
; CHECK-ZVBB-NEXT: vsetvli zero, a0, e16, mf4, ta, ma
2645+
; CHECK-ZVBB-NEXT: vsll.vi v8, v8, 7, v0.t
2646+
; CHECK-ZVBB-NEXT: vnot.v v8, v8, v0.t
2647+
; CHECK-ZVBB-NEXT: vclz.v v8, v8, v0.t
2648+
; CHECK-ZVBB-NEXT: ret
2649+
%va.not = xor <vscale x 1 x i9> %va, splat (i9 -1)
2650+
%v = call <vscale x 1 x i9> @llvm.vp.ctlz.nxv1i9(<vscale x 1 x i9> %va.not, i1 false, <vscale x 1 x i1> %m, i32 %evl)
2651+
ret <vscale x 1 x i9> %v
2652+
}
2653+
define <vscale x 1 x i9> @vp_ctlo_zero_undef_nxv1i9(<vscale x 1 x i9> %va, <vscale x 1 x i1> %m, i32 zeroext %evl) {
2654+
; CHECK-LABEL: vp_ctlo_zero_undef_nxv1i9:
2655+
; CHECK: # %bb.0:
2656+
; CHECK-NEXT: vsetvli zero, a0, e16, mf4, ta, ma
2657+
; CHECK-NEXT: vsll.vi v8, v8, 7, v0.t
2658+
; CHECK-NEXT: vnot.v v8, v8, v0.t
2659+
; CHECK-NEXT: vfwcvt.f.xu.v v9, v8, v0.t
2660+
; CHECK-NEXT: vsetvli zero, zero, e32, mf2, ta, ma
2661+
; CHECK-NEXT: vsrl.vi v8, v9, 23, v0.t
2662+
; CHECK-NEXT: vsetvli zero, zero, e16, mf4, ta, ma
2663+
; CHECK-NEXT: vnsrl.wi v8, v8, 0, v0.t
2664+
; CHECK-NEXT: li a0, 142
2665+
; CHECK-NEXT: vrsub.vx v8, v8, a0, v0.t
2666+
; CHECK-NEXT: ret
2667+
;
2668+
; CHECK-ZVBB-LABEL: vp_ctlo_zero_undef_nxv1i9:
2669+
; CHECK-ZVBB: # %bb.0:
2670+
; CHECK-ZVBB-NEXT: vsetvli zero, a0, e16, mf4, ta, ma
2671+
; CHECK-ZVBB-NEXT: vsll.vi v8, v8, 7, v0.t
2672+
; CHECK-ZVBB-NEXT: vnot.v v8, v8, v0.t
2673+
; CHECK-ZVBB-NEXT: vclz.v v8, v8, v0.t
2674+
; CHECK-ZVBB-NEXT: ret
2675+
%va.not = xor <vscale x 1 x i9> %va, splat (i9 -1)
2676+
%v = call <vscale x 1 x i9> @llvm.vp.ctlz.nxv1i9(<vscale x 1 x i9> %va.not, i1 true, <vscale x 1 x i1> %m, i32 %evl)
2677+
ret <vscale x 1 x i9> %v
2678+
}
26272679
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
26282680
; RV32: {{.*}}
26292681
; RV64: {{.*}}

0 commit comments

Comments
 (0)