Skip to content

Commit 9afc64b

Browse files
authored
Introduce verification of integer address type widths. (#10209)
* cranelift/codegen/verifier: Add verification of pointer width (#10118) This adds a check to load that confirms the pointer width is as expected according to the target. * cranelift/verifier: Add load pointer width verification. Also clarify width of integer address type and unit tests that check the new verifier rule. * cranelift/filetests: Split out 64 and 32 bit loads. Makes unit test pass with the verifier checking the load address size. * cranelift/verifier: Add address verification to more instructions. Also adds unit tests to ensure problematic cases are detected. * cranelift/verifier: Change wording, restructure arms.
1 parent e2f55ab commit 9afc64b

File tree

16 files changed

+623
-190
lines changed

16 files changed

+623
-190
lines changed

cranelift/codegen/meta/src/gen_inst.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1233,6 +1233,9 @@ fn gen_builder(
12331233
12341234
There is also a method per instruction format. These methods all
12351235
return an `Inst`.
1236+
1237+
When an address to a load or store is specified, its integer
1238+
size is required to be equal to the platform's pointer width.
12361239
"#,
12371240
);
12381241
fmt.line("pub trait InstBuilder<'f>: InstBuilderBase<'f> {");

cranelift/codegen/src/verifier/mod.rs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -663,6 +663,40 @@ impl<'a> Verifier<'a> {
663663
} => {
664664
self.verify_bitcast(inst, flags, arg, errors)?;
665665
}
666+
LoadNoOffset { opcode, arg, .. } if opcode.can_load() => {
667+
self.verify_is_address(inst, arg, errors)?;
668+
}
669+
Load { opcode, arg, .. } if opcode.can_load() => {
670+
self.verify_is_address(inst, arg, errors)?;
671+
}
672+
AtomicCas {
673+
opcode,
674+
args: [p, _, _],
675+
..
676+
} if opcode.can_load() || opcode.can_store() => {
677+
self.verify_is_address(inst, p, errors)?;
678+
}
679+
AtomicRmw {
680+
opcode,
681+
args: [p, _],
682+
..
683+
} if opcode.can_load() || opcode.can_store() => {
684+
self.verify_is_address(inst, p, errors)?;
685+
}
686+
Store {
687+
opcode,
688+
args: [_, p],
689+
..
690+
} if opcode.can_store() => {
691+
self.verify_is_address(inst, p, errors)?;
692+
}
693+
StoreNoOffset {
694+
opcode,
695+
args: [_, p],
696+
..
697+
} if opcode.can_store() => {
698+
self.verify_is_address(inst, p, errors)?;
699+
}
666700
UnaryConst {
667701
opcode: opcode @ (Opcode::Vconst | Opcode::F128const),
668702
constant_handle,
@@ -1046,6 +1080,31 @@ impl<'a> Verifier<'a> {
10461080
}
10471081
}
10481082

1083+
fn verify_is_address(
1084+
&self,
1085+
loc_inst: Inst,
1086+
v: Value,
1087+
errors: &mut VerifierErrors,
1088+
) -> VerifierStepResult {
1089+
if let Some(isa) = self.isa {
1090+
let pointer_width = isa.triple().pointer_width()?;
1091+
let value_type = self.func.dfg.value_type(v);
1092+
let expected_width = pointer_width.bits() as u32;
1093+
let value_width = value_type.bits();
1094+
if expected_width != value_width {
1095+
errors.nonfatal((
1096+
loc_inst,
1097+
self.context(loc_inst),
1098+
format!("invalid pointer width (got {value_width}, expected {expected_width}) encountered {v}"),
1099+
))
1100+
} else {
1101+
Ok(())
1102+
}
1103+
} else {
1104+
Ok(())
1105+
}
1106+
}
1107+
10491108
fn domtree_integrity(
10501109
&self,
10511110
domtree: &DominatorTree,

cranelift/filetests/filetests/runtests/fdemote.clif

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -73,21 +73,3 @@ block0(v0: f64):
7373
; run: %fdemote_is_nan(-sNaN:0x1) == 1
7474
; run: %fdemote_is_nan(+sNaN:0x4000000000001) == 1
7575
; run: %fdemote_is_nan(-sNaN:0x4000000000001) == 1
76-
77-
78-
;; Tests a fdemote+load combo which some backends may optimize
79-
function %fdemote_load(i64, f64) -> f32 {
80-
ss0 = explicit_slot 16
81-
82-
block0(v1: i64, v2: f64):
83-
v3 = stack_addr.i64 ss0
84-
store.f64 v2, v3
85-
v4 = load.f64 v3
86-
v5 = fdemote.f32 v4
87-
return v5
88-
}
89-
; run: %fdemote_load(0, 0x0.0) == 0x0.0
90-
; run: %fdemote_load(1, 0x0.1) == 0x0.1
91-
; run: %fdemote_load(2, 0x0.2) == 0x0.2
92-
; run: %fdemote_load(3, 0x3.2) == 0x3.2
93-
; run: %fdemote_load(0x8, 0x3.2) == 0x3.2
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
test interpret
2+
test run
3+
target pulley32
4+
target pulley32be
5+
6+
;; Tests a fdemote+load combo which some backends may optimize
7+
function %fdemote_load(i32, f64) -> f32 {
8+
ss0 = explicit_slot 16
9+
10+
block0(v1: i32, v2: f64):
11+
v3 = stack_addr.i32 ss0
12+
store.f64 v2, v3
13+
v4 = load.f64 v3
14+
v5 = fdemote.f32 v4
15+
return v5
16+
}
17+
; run: %fdemote_load(0, 0x0.0) == 0x0.0
18+
; run: %fdemote_load(1, 0x0.1) == 0x0.1
19+
; run: %fdemote_load(2, 0x0.2) == 0x0.2
20+
; run: %fdemote_load(3, 0x3.2) == 0x3.2
21+
; run: %fdemote_load(0x8, 0x3.2) == 0x3.2
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
test interpret
2+
test run
3+
target x86_64
4+
target x86_64 has_avx
5+
target s390x
6+
target aarch64
7+
target riscv64
8+
target pulley64
9+
target pulley64be
10+
11+
;; Tests a fdemote+load combo which some backends may optimize
12+
function %fdemote_load(i64, f64) -> f32 {
13+
ss0 = explicit_slot 16
14+
15+
block0(v1: i64, v2: f64):
16+
v3 = stack_addr.i64 ss0
17+
store.f64 v2, v3
18+
v4 = load.f64 v3
19+
v5 = fdemote.f32 v4
20+
return v5
21+
}
22+
; run: %fdemote_load(0, 0x0.0) == 0x0.0
23+
; run: %fdemote_load(1, 0x0.1) == 0x0.1
24+
; run: %fdemote_load(2, 0x0.2) == 0x0.2
25+
; run: %fdemote_load(3, 0x3.2) == 0x3.2
26+
; run: %fdemote_load(0x8, 0x3.2) == 0x3.2

cranelift/filetests/filetests/runtests/fpromote.clif

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -83,20 +83,3 @@ block0(v0: f32):
8383
; run: %fpromote_is_nan(+sNaN:0x200001) == 1
8484
; run: %fpromote_is_nan(-sNaN:0x200001) == 1
8585

86-
87-
;; Tests a fpromote+load combo which some backends may optimize
88-
function %fpromote_load(i64, f32) -> f64 {
89-
ss0 = explicit_slot 16
90-
91-
block0(v1: i64, v2: f32):
92-
v3 = stack_addr.i64 ss0
93-
store.f32 v2, v3
94-
v4 = load.f32 v3
95-
v5 = fpromote.f64 v4
96-
return v5
97-
}
98-
; run: %fpromote_load(0, 0x0.0) == 0x0.0
99-
; run: %fpromote_load(1, 0x0.1) == 0x0.1
100-
; run: %fpromote_load(2, 0x0.2) == 0x0.2
101-
; run: %fpromote_load(3, 0x3.2) == 0x3.2
102-
; run: %fpromote_load(0xC, 0x3.2) == 0x3.2
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
test interpret
2+
test run
3+
target pulley32
4+
target pulley32be
5+
6+
;; Tests a fpromote+load combo which some backends may optimize
7+
function %fpromote_load(i64, f32) -> f64 {
8+
ss0 = explicit_slot 16
9+
10+
block0(v1: i64, v2: f32):
11+
v3 = stack_addr.i32 ss0
12+
store.f32 v2, v3
13+
v4 = load.f32 v3
14+
v5 = fpromote.f64 v4
15+
return v5
16+
}
17+
; run: %fpromote_load(0, 0x0.0) == 0x0.0
18+
; run: %fpromote_load(1, 0x0.1) == 0x0.1
19+
; run: %fpromote_load(2, 0x0.2) == 0x0.2
20+
; run: %fpromote_load(3, 0x3.2) == 0x3.2
21+
; run: %fpromote_load(0xC, 0x3.2) == 0x3.2
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
test interpret
2+
test run
3+
target x86_64
4+
target x86_64 has_avx
5+
target s390x
6+
target aarch64
7+
target riscv64
8+
target riscv64 has_c has_zcb
9+
target pulley64
10+
target pulley64be
11+
12+
;; Tests a fpromote+load combo which some backends may optimize
13+
function %fpromote_load(i64, f32) -> f64 {
14+
ss0 = explicit_slot 16
15+
16+
block0(v1: i64, v2: f32):
17+
v3 = stack_addr.i64 ss0
18+
store.f32 v2, v3
19+
v4 = load.f32 v3
20+
v5 = fpromote.f64 v4
21+
return v5
22+
}
23+
; run: %fpromote_load(0, 0x0.0) == 0x0.0
24+
; run: %fpromote_load(1, 0x0.1) == 0x0.1
25+
; run: %fpromote_load(2, 0x0.2) == 0x0.2
26+
; run: %fpromote_load(3, 0x3.2) == 0x3.2
27+
; run: %fpromote_load(0xC, 0x3.2) == 0x3.2

cranelift/filetests/filetests/runtests/simd-extractlane.clif

Lines changed: 0 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -43,72 +43,6 @@ block0(v0: i64x2):
4343
}
4444
; run: %extractlane_1([0 4294967297]) == 4294967297
4545

46-
function %extractlane_i8x16_through_stack(i8x16) -> i8 {
47-
ss0 = explicit_slot 8
48-
block0(v0: i8x16):
49-
v2 = stack_addr.i64 ss0
50-
v3 = extractlane v0, 1
51-
store v3, v2
52-
v4 = load.i8 v2
53-
return v4
54-
}
55-
; run: %extractlane_i8x16_through_stack([1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]) == 2
56-
57-
function %extractlane_i16x8_through_stack(i16x8) -> i16 {
58-
ss0 = explicit_slot 8
59-
block0(v0: i16x8):
60-
v2 = stack_addr.i64 ss0
61-
v3 = extractlane v0, 2
62-
store v3, v2
63-
v4 = load.i16 v2
64-
return v4
65-
}
66-
; run: %extractlane_i16x8_through_stack([1 2 3 4 5 6 7 8]) == 3
67-
68-
function %extractlane_i32x4_through_stack(i32x4) -> i32 {
69-
ss0 = explicit_slot 8
70-
block0(v0: i32x4):
71-
v2 = stack_addr.i64 ss0
72-
v3 = extractlane v0, 3
73-
store v3, v2
74-
v4 = load.i32 v2
75-
return v4
76-
}
77-
; run: %extractlane_i32x4_through_stack([1 2 3 4]) == 4
78-
79-
function %extractlane_i64x2_through_stack(i64x2) -> i64 {
80-
ss0 = explicit_slot 8
81-
block0(v0: i64x2):
82-
v2 = stack_addr.i64 ss0
83-
v3 = extractlane v0, 0
84-
store v3, v2
85-
v4 = load.i64 v2
86-
return v4
87-
}
88-
; run: %extractlane_i64x2_through_stack([1 2]) == 1
89-
90-
function %extractlane_f32x4_through_stack(f32x4) -> f32 {
91-
ss0 = explicit_slot 8
92-
block0(v0: f32x4):
93-
v2 = stack_addr.i64 ss0
94-
v3 = extractlane v0, 3
95-
store v3, v2
96-
v4 = load.f32 v2
97-
return v4
98-
}
99-
; run: %extractlane_f32x4_through_stack([0x1.0 0x2.0 0x3.0 0x4.0]) == 0x4.0
100-
101-
function %extractlane_f64x2_through_stack(f64x2) -> f64 {
102-
ss0 = explicit_slot 8
103-
block0(v0: f64x2):
104-
v2 = stack_addr.i64 ss0
105-
v3 = extractlane v0, 0
106-
store v3, v2
107-
v4 = load.f64 v2
108-
return v4
109-
}
110-
; run: %extractlane_f64x2_through_stack([0x1.0 0x2.0]) == 0x1.0
111-
11246

11347
function %unaligned_extractlane() -> f64 {
11448
ss0 = explicit_slot 24
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
test interpret
2+
test run
3+
target pulley32
4+
target pulley32be
5+
6+
function %extractlane_i8x16_through_stack(i8x16) -> i8 {
7+
ss0 = explicit_slot 8
8+
block0(v0: i8x16):
9+
v2 = stack_addr.i32 ss0
10+
v3 = extractlane v0, 1
11+
store v3, v2
12+
v4 = load.i8 v2
13+
return v4
14+
}
15+
; run: %extractlane_i8x16_through_stack([1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]) == 2
16+
17+
function %extractlane_i16x8_through_stack(i16x8) -> i16 {
18+
ss0 = explicit_slot 8
19+
block0(v0: i16x8):
20+
v2 = stack_addr.i32 ss0
21+
v3 = extractlane v0, 2
22+
store v3, v2
23+
v4 = load.i16 v2
24+
return v4
25+
}
26+
; run: %extractlane_i16x8_through_stack([1 2 3 4 5 6 7 8]) == 3
27+
28+
function %extractlane_i32x4_through_stack(i32x4) -> i32 {
29+
ss0 = explicit_slot 8
30+
block0(v0: i32x4):
31+
v2 = stack_addr.i32 ss0
32+
v3 = extractlane v0, 3
33+
store v3, v2
34+
v4 = load.i32 v2
35+
return v4
36+
}
37+
; run: %extractlane_i32x4_through_stack([1 2 3 4]) == 4
38+
39+
function %extractlane_i64x2_through_stack(i64x2) -> i64 {
40+
ss0 = explicit_slot 8
41+
block0(v0: i64x2):
42+
v2 = stack_addr.i32 ss0
43+
v3 = extractlane v0, 0
44+
store v3, v2
45+
v4 = load.i64 v2
46+
return v4
47+
}
48+
; run: %extractlane_i64x2_through_stack([1 2]) == 1
49+
50+
function %extractlane_f32x4_through_stack(f32x4) -> f32 {
51+
ss0 = explicit_slot 8
52+
block0(v0: f32x4):
53+
v2 = stack_addr.i32 ss0
54+
v3 = extractlane v0, 3
55+
store v3, v2
56+
v4 = load.f32 v2
57+
return v4
58+
}
59+
; run: %extractlane_f32x4_through_stack([0x1.0 0x2.0 0x3.0 0x4.0]) == 0x4.0
60+
61+
function %extractlane_f64x2_through_stack(f64x2) -> f64 {
62+
ss0 = explicit_slot 8
63+
block0(v0: f64x2):
64+
v2 = stack_addr.i32 ss0
65+
v3 = extractlane v0, 0
66+
store v3, v2
67+
v4 = load.f64 v2
68+
return v4
69+
}
70+
; run: %extractlane_f64x2_through_stack([0x1.0 0x2.0]) == 0x1.0

0 commit comments

Comments
 (0)