Skip to content

Commit c092c5f

Browse files
committed
[PowerPC] Add AMO load builtins for conditional increment/decrement
1 parent 303c2d6 commit c092c5f

File tree

10 files changed

+259
-1
lines changed

10 files changed

+259
-1
lines changed

clang/include/clang/Basic/BuiltinsPPC.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,6 +1006,10 @@ TARGET_BUILTIN(__builtin_amo_lwat, "UiUi*UiIi", "", "isa-v30-instructions")
10061006
TARGET_BUILTIN(__builtin_amo_ldat, "ULiULi*ULiIi", "", "isa-v30-instructions")
10071007
TARGET_BUILTIN(__builtin_amo_lwat_s, "SiSi*SiIi", "", "isa-v30-instructions")
10081008
TARGET_BUILTIN(__builtin_amo_ldat_s, "SLiSLi*SLiIi", "", "isa-v30-instructions")
1009+
TARGET_BUILTIN(__builtin_amo_lwat_cond, "UiUi*Ii", "", "isa-v30-instructions")
1010+
TARGET_BUILTIN(__builtin_amo_ldat_cond, "ULiULi*Ii", "", "isa-v30-instructions")
1011+
TARGET_BUILTIN(__builtin_amo_lwat_cond_s, "SiSi*Ii", "", "isa-v30-instructions")
1012+
TARGET_BUILTIN(__builtin_amo_ldat_cond_s, "SLiSLi*Ii", "", "isa-v30-instructions")
10091013

10101014
// Set the floating point rounding mode
10111015
BUILTIN(__builtin_setrnd, "di", "")

clang/lib/CodeGen/TargetBuiltins/PPC.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1374,5 +1374,17 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
13741374
return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::ppc_amo_ldat),
13751375
{Op0, Op1, Op2});
13761376
}
1377+
case PPC::BI__builtin_amo_lwat_cond_s: {
1378+
Value *Op0 = EmitScalarExpr(E->getArg(0));
1379+
Value *Op1 = EmitScalarExpr(E->getArg(1));
1380+
return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::ppc_amo_lwat_cond),
1381+
{Op0, Op1});
1382+
}
1383+
case PPC::BI__builtin_amo_ldat_cond_s: {
1384+
Value *Op0 = EmitScalarExpr(E->getArg(0));
1385+
Value *Op1 = EmitScalarExpr(E->getArg(1));
1386+
return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::ppc_amo_ldat_cond),
1387+
{Op0, Op1});
1388+
}
13771389
}
13781390
}

clang/lib/Sema/SemaPPC.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,10 @@ static bool isPPC_64Builtin(unsigned BuiltinID) {
9191
case PPC::BI__builtin_amo_ldat:
9292
case PPC::BI__builtin_amo_lwat_s:
9393
case PPC::BI__builtin_amo_ldat_s:
94+
case PPC::BI__builtin_amo_lwat_cond:
95+
case PPC::BI__builtin_amo_ldat_cond:
96+
case PPC::BI__builtin_amo_lwat_cond_s:
97+
case PPC::BI__builtin_amo_ldat_cond_s:
9498
return true;
9599
}
96100
return false;
@@ -281,6 +285,21 @@ bool SemaPPC::CheckPPCBuiltinFunctionCall(const TargetInfo &TI,
281285
<< toString(Result, 10) << (IsUnsigned ? "0-4, 6" : "0, 5, 7") << "8"
282286
<< Arg->getSourceRange();
283287
}
288+
case PPC::BI__builtin_amo_lwat_cond:
289+
case PPC::BI__builtin_amo_ldat_cond:
290+
case PPC::BI__builtin_amo_lwat_cond_s:
291+
case PPC::BI__builtin_amo_ldat_cond_s: {
292+
llvm::APSInt Result;
293+
if (SemaRef.BuiltinConstantArg(TheCall, 1, Result))
294+
return true;
295+
unsigned Val = Result.getZExtValue();
296+
if (llvm::is_contained({24u, 25u, 28u}, Val))
297+
return false;
298+
299+
Expr *Arg = TheCall->getArg(1);
300+
return SemaRef.Diag(Arg->getBeginLoc(), diag::err_argument_invalid_range)
301+
<< toString(Result, 10) << "24, 25" << "28" << Arg->getSourceRange();
302+
}
284303
}
285304
llvm_unreachable("must return from switch");
286305
}

clang/test/CodeGen/PowerPC/builtins-amo-err.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,28 @@ void test_amo() {
2727
__builtin_amo_ldat_s(ptr4, value4, 5);
2828
// FC-ERROR: error: argument value 6 is outside the valid range [0, 5, 7, 8]
2929
__builtin_amo_ldat_s(ptr4, value4, 6);
30+
31+
unsigned int *ptr5;
32+
// AIX32-ERROR-COUNT-2: error: this builtin is only available on 64-bit targets
33+
__builtin_amo_lwat_cond(ptr5, 24);
34+
// FC-ERROR: argument value 20 is outside the valid range [24, 25, 28]
35+
__builtin_amo_lwat_cond(ptr5, 20);
36+
37+
unsigned long int *ptr6;
38+
// AIX32-ERROR-COUNT-2: error: this builtin is only available on 64-bit targets
39+
__builtin_amo_ldat_cond(ptr6, 28);
40+
// FC-ERROR: argument value 0 is outside the valid range [24, 25, 28]
41+
__builtin_amo_ldat_cond(ptr6, 0);
42+
43+
signed int *ptr7;
44+
// AIX32-ERROR-COUNT-2: error: this builtin is only available on 64-bit targets
45+
__builtin_amo_lwat_cond_s(ptr7, 24);
46+
// FC-ERROR: argument value 20 is outside the valid range [24, 25, 28]
47+
__builtin_amo_lwat_cond_s(ptr7, 20);
48+
49+
signed long int *ptr8;
50+
// AIX32-ERROR-COUNT-2: error: this builtin is only available on 64-bit targets
51+
__builtin_amo_ldat_cond_s(ptr6, 28);
52+
// FC-ERROR: argument value 0 is outside the valid range [24, 25, 28]
53+
__builtin_amo_ldat_cond_s(ptr6, 0);
3054
}

clang/test/CodeGen/PowerPC/builtins-ppc-amo.c

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ void test_signed_lwat(int *ptr, int value, int * resp) {
6161
*resp = res;
6262
}
6363

64-
6564
// CHECK-LABEL: define dso_local void @test_signed_ldat(
6665
// CHECK-SAME: ptr noundef [[PTR:%.*]], i64 noundef [[VALUE:%.*]], ptr noundef writeonly captures(none) initializes((0, 8)) [[RESP:%.*]]) local_unnamed_addr #[[ATTR0]] {
6766
// CHECK-NEXT: [[ENTRY:.*:]]
@@ -81,6 +80,82 @@ void test_signed_ldat(long int *ptr, long int value, long int * resp) {
8180
*resp = res;
8281
}
8382

83+
// CHECK-LABEL: define dso_local void @test_unsigned_lwat_cond(
84+
// CHECK-SAME: ptr noundef [[PTR:%.*]], ptr noundef writeonly captures(none) initializes((0, 4)) [[RESP:%.*]]) local_unnamed_addr #[[ATTR0]] {
85+
// CHECK-NEXT: [[ENTRY:.*:]]
86+
// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.ppc.amo.lwat.cond(ptr [[PTR]], i32 24)
87+
// CHECK-NEXT: store i32 [[TMP0]], ptr [[RESP]], align 4, !tbaa [[INT_TBAA2]]
88+
// CHECK-NEXT: ret void
89+
//
90+
// AIX-LABEL: define void @test_unsigned_lwat_cond(
91+
// AIX-SAME: ptr noundef [[PTR:%.*]], ptr noundef writeonly captures(none) initializes((0, 4)) [[RESP:%.*]]) local_unnamed_addr #[[ATTR0]] {
92+
// AIX-NEXT: [[ENTRY:.*:]]
93+
// AIX-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.ppc.amo.lwat.cond(ptr [[PTR]], i32 24)
94+
// AIX-NEXT: store i32 [[TMP0]], ptr [[RESP]], align 4, !tbaa [[INT_TBAA2]]
95+
// AIX-NEXT: ret void
96+
//
97+
void test_unsigned_lwat_cond(unsigned int *ptr, unsigned int * resp) {
98+
unsigned int res = __builtin_amo_lwat_cond(ptr, 24);
99+
*resp = res;
100+
}
101+
102+
// CHECK-LABEL: define dso_local void @test_unsigned_ldat_cond(
103+
// CHECK-SAME: ptr noundef [[PTR:%.*]], ptr noundef writeonly captures(none) initializes((0, 8)) [[RESP:%.*]]) local_unnamed_addr #[[ATTR0]] {
104+
// CHECK-NEXT: [[ENTRY:.*:]]
105+
// CHECK-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.ppc.amo.ldat.cond(ptr [[PTR]], i32 25)
106+
// CHECK-NEXT: store i64 [[TMP0]], ptr [[RESP]], align 8, !tbaa [[LONG_TBAA6]]
107+
// CHECK-NEXT: ret void
108+
//
109+
// AIX-LABEL: define void @test_unsigned_ldat_cond(
110+
// AIX-SAME: ptr noundef [[PTR:%.*]], ptr noundef writeonly captures(none) initializes((0, 8)) [[RESP:%.*]]) local_unnamed_addr #[[ATTR0]] {
111+
// AIX-NEXT: [[ENTRY:.*:]]
112+
// AIX-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.ppc.amo.ldat.cond(ptr [[PTR]], i32 25)
113+
// AIX-NEXT: store i64 [[TMP0]], ptr [[RESP]], align 8, !tbaa [[LONG_TBAA6]]
114+
// AIX-NEXT: ret void
115+
//
116+
void test_unsigned_ldat_cond(unsigned long int *ptr, unsigned long int * resp) {
117+
unsigned long int res = __builtin_amo_ldat_cond(ptr, 25);
118+
*resp = res;
119+
}
120+
121+
// CHECK-LABEL: define dso_local void @test_signed_lwat_cond(
122+
// CHECK-SAME: ptr noundef [[PTR:%.*]], ptr noundef writeonly captures(none) initializes((0, 4)) [[RESP:%.*]]) local_unnamed_addr #[[ATTR0]] {
123+
// CHECK-NEXT: [[ENTRY:.*:]]
124+
// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.ppc.amo.lwat.cond(ptr [[PTR]], i32 24)
125+
// CHECK-NEXT: store i32 [[TMP0]], ptr [[RESP]], align 4, !tbaa [[INT_TBAA2]]
126+
// CHECK-NEXT: ret void
127+
//
128+
// AIX-LABEL: define void @test_signed_lwat_cond(
129+
// AIX-SAME: ptr noundef [[PTR:%.*]], ptr noundef writeonly captures(none) initializes((0, 4)) [[RESP:%.*]]) local_unnamed_addr #[[ATTR0]] {
130+
// AIX-NEXT: [[ENTRY:.*:]]
131+
// AIX-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.ppc.amo.lwat.cond(ptr [[PTR]], i32 24)
132+
// AIX-NEXT: store i32 [[TMP0]], ptr [[RESP]], align 4, !tbaa [[INT_TBAA2]]
133+
// AIX-NEXT: ret void
134+
//
135+
void test_signed_lwat_cond(int *ptr, int * resp) {
136+
int res = __builtin_amo_lwat_cond_s(ptr, 24);
137+
*resp = res;
138+
}
139+
140+
// CHECK-LABEL: define dso_local void @test_signed_ldat_cond(
141+
// CHECK-SAME: ptr noundef [[PTR:%.*]], ptr noundef writeonly captures(none) initializes((0, 8)) [[RESP:%.*]]) local_unnamed_addr #[[ATTR0]] {
142+
// CHECK-NEXT: [[ENTRY:.*:]]
143+
// CHECK-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.ppc.amo.ldat.cond(ptr [[PTR]], i32 25)
144+
// CHECK-NEXT: store i64 [[TMP0]], ptr [[RESP]], align 8, !tbaa [[LONG_TBAA6]]
145+
// CHECK-NEXT: ret void
146+
//
147+
// AIX-LABEL: define void @test_signed_ldat_cond(
148+
// AIX-SAME: ptr noundef [[PTR:%.*]], ptr noundef writeonly captures(none) initializes((0, 8)) [[RESP:%.*]]) local_unnamed_addr #[[ATTR0]] {
149+
// AIX-NEXT: [[ENTRY:.*:]]
150+
// AIX-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.ppc.amo.ldat.cond(ptr [[PTR]], i32 25)
151+
// AIX-NEXT: store i64 [[TMP0]], ptr [[RESP]], align 8, !tbaa [[LONG_TBAA6]]
152+
// AIX-NEXT: ret void
153+
//
154+
void test_signed_ldat_cond(long int *ptr, long int * resp) {
155+
long int res = __builtin_amo_ldat_cond_s(ptr, 25);
156+
*resp = res;
157+
}
158+
84159
//.
85160
// CHECK: [[INT_TBAA2]] = !{[[META3:![0-9]+]], [[META3]], i64 0}
86161
// CHECK: [[META3]] = !{!"int", [[META4:![0-9]+]], i64 0}

llvm/include/llvm/IR/IntrinsicsPowerPC.td

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2150,4 +2150,12 @@ let TargetPrefix = "ppc" in {
21502150
DefaultAttrsIntrinsic<[llvm_i64_ty],[llvm_ptr_ty,
21512151
llvm_i64_ty, llvm_i32_ty],
21522152
[IntrArgMemOnly, ImmArg<ArgIndex<2>>]>;
2153+
def int_ppc_amo_lwat_cond : ClangBuiltin<"__builtin_amo_lwat_cond">,
2154+
DefaultAttrsIntrinsic<[llvm_i32_ty],[llvm_ptr_ty,
2155+
llvm_i32_ty],
2156+
[IntrArgMemOnly, ImmArg<ArgIndex<1>>]>;
2157+
def int_ppc_amo_ldat_cond : ClangBuiltin<"__builtin_amo_ldat_cond">,
2158+
DefaultAttrsIntrinsic<[llvm_i64_ty],[llvm_ptr_ty,
2159+
llvm_i32_ty],
2160+
[IntrArgMemOnly, ImmArg<ArgIndex<1>>]>;
21532161
}

llvm/lib/Target/PowerPC/PPCISelLowering.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14757,6 +14757,32 @@ PPCTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
1475714757
else
1475814758
BuildMI(*BB, MI, DL, TII->get(TargetOpcode::COPY), DstReg)
1475914759
.addReg(Result64);
14760+
} else if (MI.getOpcode() == PPC::LWAT_COND_PSEUDO ||
14761+
MI.getOpcode() == PPC::LDAT_COND_PSEUDO) {
14762+
DebugLoc DL = MI.getDebugLoc();
14763+
Register DstReg = MI.getOperand(0).getReg();
14764+
Register PtrReg = MI.getOperand(1).getReg();
14765+
unsigned FC = MI.getOperand(2).getImm();
14766+
bool IsLwat_Cond = MI.getOpcode() == PPC::LWAT_COND_PSEUDO;
14767+
14768+
Register Pair = MRI.createVirtualRegister(&PPC::G8pRCRegClass);
14769+
BuildMI(*BB, MI, DL, TII->get(TargetOpcode::IMPLICIT_DEF), Pair);
14770+
14771+
Register PairResult = MRI.createVirtualRegister(&PPC::G8pRCRegClass);
14772+
BuildMI(*BB, MI, DL, TII->get(IsLwat_Cond ? PPC::LWAT : PPC::LDAT),
14773+
PairResult)
14774+
.addReg(Pair)
14775+
.addReg(PtrReg)
14776+
.addImm(FC);
14777+
Register Result64 = MRI.createVirtualRegister(&PPC::G8RCRegClass);
14778+
BuildMI(*BB, MI, DL, TII->get(TargetOpcode::COPY), Result64)
14779+
.addReg(PairResult, 0, PPC::sub_gp8_x0);
14780+
if (IsLwat_Cond)
14781+
BuildMI(*BB, MI, DL, TII->get(TargetOpcode::COPY), DstReg)
14782+
.addReg(Result64, 0, PPC::sub_32);
14783+
else
14784+
BuildMI(*BB, MI, DL, TII->get(TargetOpcode::COPY), DstReg)
14785+
.addReg(Result64);
1476014786
} else {
1476114787
llvm_unreachable("Unexpected instr type to insert");
1476214788
}

llvm/lib/Target/PowerPC/PPCInstr64Bit.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,12 @@ def LDAT_PSEUDO : PPCCustomInserterPseudo<
340340
"#LDAT_PSEUDO",
341341
[(set i64:$dst, (int_ppc_amo_ldat ptr_rc_nor0:$ptr, g8rc:$val, timm:$fc))]>;
342342

343+
def LDAT_COND_PSEUDO : PPCCustomInserterPseudo <
344+
(outs g8rc:$dst),
345+
(ins ptr_rc_nor0:$ptr, u5imm:$fc),
346+
"#LDAT_COND_PSEUDO",
347+
[(set i64:$dst, (int_ppc_amo_ldat_cond ptr_rc_nor0:$ptr, timm:$fc))]>;
348+
343349
let Defs = [CR0], mayStore = 1, mayLoad = 0, hasSideEffects = 0 in {
344350
def STDCX : XForm_1_memOp<31, 214, (outs), (ins g8rc:$RST, (memrr $RA, $RB):$addr),
345351
"stdcx. $RST, $addr", IIC_LdStSTDCX, []>, isRecordForm;

llvm/lib/Target/PowerPC/PPCInstrInfo.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1879,6 +1879,12 @@ def LWAT_PSEUDO : PPCCustomInserterPseudo<
18791879
"#LWAT_PSEUDO",
18801880
[(set i32:$dst, (int_ppc_amo_lwat ptr_rc_nor0:$ptr, gprc:$val, timm:$fc))]>;
18811881

1882+
def LWAT_COND_PSEUDO : PPCCustomInserterPseudo <
1883+
(outs gprc:$dst),
1884+
(ins ptr_rc_nor0:$ptr, u5imm:$fc),
1885+
"#LWAT_COND_PSEUDO",
1886+
[(set i32:$dst, (int_ppc_amo_lwat_cond ptr_rc_nor0:$ptr, timm:$fc))]>;
1887+
18821888
let Defs = [CR0], mayStore = 1, mayLoad = 0, hasSideEffects = 0 in {
18831889
def STBCX : XForm_1_memOp<31, 694, (outs), (ins gprc:$RST, (memrr $RA, $RB):$addr),
18841890
"stbcx. $RST, $addr", IIC_LdStSTWCX, []>,

llvm/test/CodeGen/PowerPC/amo-enable.ll

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,5 +46,83 @@ entry:
4646
ret void
4747
}
4848

49+
define void @test_s_lwat(ptr noundef %ptr, i32 noundef %value, ptr nocapture %resp) {
50+
; CHECK-LABEL: test_s_lwat:
51+
; CHECK: # %bb.0: # %entry
52+
; CHECK-NEXT: mr r7, r4
53+
; CHECK-NEXT: lwat r6, r3, 0
54+
; CHECK-NEXT: stw r6, 0(r5)
55+
; CHECK-NEXT: blr
56+
;
57+
; CHECK-BE-LABEL: test_s_lwat:
58+
; CHECK-BE: # %bb.0: # %entry
59+
; CHECK-BE-NEXT: mr r7, r4
60+
; CHECK-BE-NEXT: lwat r6, r3, 0
61+
; CHECK-BE-NEXT: stw r6, 0(r5)
62+
; CHECK-BE-NEXT: blr
63+
entry:
64+
%0 = tail call i32 @llvm.ppc.amo.lwat(ptr %ptr, i32 %value, i32 0)
65+
store i32 %0, ptr %resp, align 4
66+
ret void
67+
}
68+
69+
define void @test_s_ldat(ptr noundef %ptr, i64 noundef %value, ptr nocapture %resp) {
70+
; CHECK-LABEL: test_s_ldat:
71+
; CHECK: # %bb.0: # %entry
72+
; CHECK-NEXT: mr r7, r4
73+
; CHECK-NEXT: ldat r6, r3, 5
74+
; CHECK-NEXT: std r6, 0(r5)
75+
; CHECK-NEXT: blr
76+
;
77+
; CHECK-BE-LABEL: test_s_ldat:
78+
; CHECK-BE: # %bb.0: # %entry
79+
; CHECK-BE-NEXT: mr r7, r4
80+
; CHECK-BE-NEXT: ldat r6, r3, 5
81+
; CHECK-BE-NEXT: std r6, 0(r5)
82+
; CHECK-BE-NEXT: blr
83+
entry:
84+
%0 = tail call i64 @llvm.ppc.amo.ldat(ptr %ptr, i64 %value, i32 5)
85+
store i64 %0, ptr %resp, align 8
86+
ret void
87+
}
88+
89+
define void @test_lwat_cond(ptr noundef %ptr, ptr nocapture %resp) {
90+
; CHECK-LABEL: test_lwat_cond:
91+
; CHECK: # %bb.0: # %entry
92+
; CHECK-NEXT: lwat r6, r3, 24
93+
; CHECK-NEXT: stw r6, 0(r4)
94+
; CHECK-NEXT: blr
95+
;
96+
; CHECK-BE-LABEL: test_lwat_cond:
97+
; CHECK-BE: # %bb.0: # %entry
98+
; CHECK-BE-NEXT: lwat r6, r3, 24
99+
; CHECK-BE-NEXT: stw r6, 0(r4)
100+
; CHECK-BE-NEXT: blr
101+
entry:
102+
%0 = tail call i32 @llvm.ppc.amo.lwat.cond(ptr %ptr, i32 24)
103+
store i32 %0, ptr %resp, align 4
104+
ret void
105+
}
106+
107+
define void @test_ldat_cond(ptr noundef %ptr, ptr nocapture %resp) {
108+
; CHECK-LABEL: test_ldat_cond:
109+
; CHECK: # %bb.0: # %entry
110+
; CHECK-NEXT: ldat r6, r3, 24
111+
; CHECK-NEXT: std r6, 0(r4)
112+
; CHECK-NEXT: blr
113+
;
114+
; CHECK-BE-LABEL: test_ldat_cond:
115+
; CHECK-BE: # %bb.0: # %entry
116+
; CHECK-BE-NEXT: ldat r6, r3, 24
117+
; CHECK-BE-NEXT: std r6, 0(r4)
118+
; CHECK-BE-NEXT: blr
119+
entry:
120+
%0 = tail call i64 @llvm.ppc.amo.ldat.cond(ptr %ptr, i32 24)
121+
store i64 %0, ptr %resp, align 8
122+
ret void
123+
}
124+
49125
declare i64 @llvm.ppc.amo.ldat(ptr, i64, i32 immarg)
50126
declare i32 @llvm.ppc.amo.lwat(ptr, i32, i32 immarg)
127+
declare i64 @llvm.ppc.amo.ldat.cond(ptr, i32 immarg)
128+
declare i32 @llvm.ppc.amo.lwat.cond(ptr, i32 immarg)

0 commit comments

Comments
 (0)