Skip to content

Commit bf362c3

Browse files
committed
Add builtin mul overflow and builtin spin lock
1 parent 1703f2d commit bf362c3

9 files changed

Lines changed: 425 additions & 0 deletions

File tree

rules/builtin/ir_refcount.json

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
{
2+
"f10": {
3+
"body": [
4+
{
5+
"text": "let (val, ovf) = "
6+
},
7+
{
8+
"method_call": {
9+
"receiver": [
10+
{
11+
"placeholder": {
12+
"arg": 0,
13+
"access": "read"
14+
}
15+
}
16+
],
17+
"body": [
18+
{
19+
"text": ".overflowing_mul("
20+
},
21+
{
22+
"placeholder": {
23+
"arg": 1,
24+
"access": "read"
25+
}
26+
},
27+
{
28+
"text": ")"
29+
}
30+
]
31+
}
32+
},
33+
{
34+
"text": ";\n "
35+
},
36+
{
37+
"method_call": {
38+
"receiver": [
39+
{
40+
"placeholder": {
41+
"arg": 2,
42+
"access": "read"
43+
}
44+
}
45+
],
46+
"body": [
47+
{
48+
"text": ".write(val)"
49+
}
50+
]
51+
}
52+
},
53+
{
54+
"text": ";\n ovf"
55+
}
56+
],
57+
"multi_statement": true,
58+
"params": {
59+
"a0": {
60+
"type": "i64"
61+
},
62+
"a1": {
63+
"type": "i64"
64+
},
65+
"a2": {
66+
"type": "Ptr<i64>",
67+
"is_refcount_pointer": true
68+
}
69+
},
70+
"return_type": {
71+
"type": "bool"
72+
}
73+
},
74+
"f9": {
75+
"body": [
76+
{
77+
"text": "let (val, ovf) = "
78+
},
79+
{
80+
"method_call": {
81+
"receiver": [
82+
{
83+
"placeholder": {
84+
"arg": 0,
85+
"access": "read"
86+
}
87+
}
88+
],
89+
"body": [
90+
{
91+
"text": ".overflowing_mul("
92+
},
93+
{
94+
"placeholder": {
95+
"arg": 1,
96+
"access": "read"
97+
}
98+
},
99+
{
100+
"text": ")"
101+
}
102+
]
103+
}
104+
},
105+
{
106+
"text": ";\n "
107+
},
108+
{
109+
"method_call": {
110+
"receiver": [
111+
{
112+
"placeholder": {
113+
"arg": 2,
114+
"access": "read"
115+
}
116+
}
117+
],
118+
"body": [
119+
{
120+
"text": ".write(val)"
121+
}
122+
]
123+
}
124+
},
125+
{
126+
"text": ";\n ovf"
127+
}
128+
],
129+
"multi_statement": true,
130+
"params": {
131+
"a0": {
132+
"type": "i64"
133+
},
134+
"a1": {
135+
"type": "i64"
136+
},
137+
"a2": {
138+
"type": "Ptr<i64>",
139+
"is_refcount_pointer": true
140+
}
141+
},
142+
"return_type": {
143+
"type": "bool"
144+
}
145+
}
146+
}

rules/builtin/ir_unsafe.json

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,74 @@
2020
"type": "usize"
2121
}
2222
},
23+
"f10": {
24+
"body": [
25+
{
26+
"text": "let (val, ovf) = "
27+
},
28+
{
29+
"method_call": {
30+
"receiver": [
31+
{
32+
"placeholder": {
33+
"arg": 0,
34+
"access": "read"
35+
}
36+
}
37+
],
38+
"body": [
39+
{
40+
"text": ".overflowing_mul("
41+
},
42+
{
43+
"placeholder": {
44+
"arg": 1,
45+
"access": "read"
46+
}
47+
},
48+
{
49+
"text": ")"
50+
}
51+
]
52+
}
53+
},
54+
{
55+
"text": ";\n *"
56+
},
57+
{
58+
"placeholder": {
59+
"arg": 2,
60+
"access": "write"
61+
}
62+
},
63+
{
64+
"text": " = val;\n ovf"
65+
}
66+
],
67+
"multi_statement": true,
68+
"params": {
69+
"a0": {
70+
"type": "i64"
71+
},
72+
"a1": {
73+
"type": "i64"
74+
},
75+
"a2": {
76+
"type": "*mut i64",
77+
"is_unsafe_pointer": true
78+
}
79+
},
80+
"return_type": {
81+
"type": "bool"
82+
}
83+
},
84+
"f11": {
85+
"body": [
86+
{
87+
"text": "std::hint::spin_loop()"
88+
}
89+
]
90+
},
2391
"f2": {
2492
"body": [
2593
{
@@ -234,5 +302,66 @@
234302
"return_type": {
235303
"type": "i32"
236304
}
305+
},
306+
"f9": {
307+
"body": [
308+
{
309+
"text": "let (val, ovf) = "
310+
},
311+
{
312+
"method_call": {
313+
"receiver": [
314+
{
315+
"placeholder": {
316+
"arg": 0,
317+
"access": "read"
318+
}
319+
}
320+
],
321+
"body": [
322+
{
323+
"text": ".overflowing_mul("
324+
},
325+
{
326+
"placeholder": {
327+
"arg": 1,
328+
"access": "read"
329+
}
330+
},
331+
{
332+
"text": ")"
333+
}
334+
]
335+
}
336+
},
337+
{
338+
"text": ";\n *"
339+
},
340+
{
341+
"placeholder": {
342+
"arg": 2,
343+
"access": "write"
344+
}
345+
},
346+
{
347+
"text": " = val;\n ovf"
348+
}
349+
],
350+
"multi_statement": true,
351+
"params": {
352+
"a0": {
353+
"type": "i64"
354+
},
355+
"a1": {
356+
"type": "i64"
357+
},
358+
"a2": {
359+
"type": "*mut i64",
360+
"is_unsafe_pointer": true
361+
}
362+
},
363+
"return_type": {
364+
"type": "bool"
365+
}
237366
}
238367
}

rules/builtin/src.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,8 @@ unsigned long long f6(unsigned long long x) { return __builtin_bswap64(x); }
2121
#endif
2222
int f7(unsigned long x) { return __builtin_ctzl(x); }
2323
int f8(unsigned long x) { return __builtin_popcountl(x); }
24+
bool f9(long a, long b, long *r) { return __builtin_mul_overflow(a, b, r); }
25+
bool f10(long long a, long long b, long long *r) { return __builtin_mul_overflow(a, b, r); }
26+
#if defined(__x86_64__) || defined(__i386__)
27+
void f11() { return __builtin_ia32_pause(); }
28+
#endif

rules/builtin/tgt_refcount.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright (c) 2022-present INESC-ID.
2+
// Distributed under the MIT license that can be found in the LICENSE file.
3+
4+
use libcc2rs::*;
5+
6+
fn f9(a0: i64, a1: i64, a2: Ptr<i64>) -> bool {
7+
let (val, ovf) = a0.overflowing_mul(a1);
8+
a2.write(val);
9+
ovf
10+
}
11+
fn f10(a0: i64, a1: i64, a2: Ptr<i64>) -> bool {
12+
let (val, ovf) = a0.overflowing_mul(a1);
13+
a2.write(val);
14+
ovf
15+
}

rules/builtin/tgt_unsafe.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,17 @@ unsafe fn f7(a0: u64) -> i32 {
2525
unsafe fn f8(a0: u64) -> i32 {
2626
a0.count_ones() as i32
2727
}
28+
unsafe fn f9(a0: i64, a1: i64, a2: *mut i64) -> bool {
29+
let (val, ovf) = a0.overflowing_mul(a1);
30+
*a2 = val;
31+
ovf
32+
}
33+
unsafe fn f10(a0: i64, a1: i64, a2: *mut i64) -> bool {
34+
let (val, ovf) = a0.overflowing_mul(a1);
35+
*a2 = val;
36+
ovf
37+
}
38+
#[cfg(any(target_arch = "x86_64", target_arch = "x86"))]
39+
unsafe fn f11() {
40+
std::hint::spin_loop()
41+
}

rules/src/modules.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ pub mod assert_tgt_unsafe;
1616
pub mod brotli_tgt_refcount;
1717
#[path = r#"../brotli/tgt_unsafe.rs"#]
1818
pub mod brotli_tgt_unsafe;
19+
#[path = r#"../builtin/tgt_refcount.rs"#]
20+
pub mod builtin_tgt_refcount;
1921
#[path = r#"../builtin/tgt_unsafe.rs"#]
2022
pub mod builtin_tgt_unsafe;
2123
#[path = r#"../carray/tgt_refcount.rs"#]

tests/unit/builtin_mul_overflow.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#include <assert.h>
2+
#include <limits.h>
3+
4+
int main() {
5+
long a = 0;
6+
assert(!__builtin_mul_overflow(3L, 7L, &a));
7+
assert(a == 21);
8+
9+
long b = 0;
10+
assert(__builtin_mul_overflow(LONG_MAX, 2L, &b));
11+
12+
long long c = 0;
13+
assert(!__builtin_mul_overflow(1000LL, 1000LL, &c));
14+
assert(c == 1000000);
15+
16+
long long d = 0;
17+
assert(__builtin_mul_overflow(LLONG_MAX, 2LL, &d));
18+
19+
return 0;
20+
}

0 commit comments

Comments
 (0)