Skip to content

Commit 84477fc

Browse files
authored
Cranelift: properly reject unimplemented big-endian loads/stores. (#10863)
At some point during the development of the Cranelift backend infrastructure, to properly support big-endian architectures such as s390x, we added explicit endianness flags to `MemFlags`, which are given to all memory operations (e.g., loads, stores, and atomic ops). In s390x in particular, the backend carefully observes these flags, because a prominent use of Cranelift (as a Wasm backend) requires explicit little-endian behavior and the system is big-endian. However, all of our other supported ISAs are little-endian and so we did not implement explicit checks at the time, instead accepting all loads and stores as an artifact of our little-endian-only origins. This PR adds explicit conditions to all ISLE rules that lower loads, stores, and atomic ops on x86-64, aarch64, and riscv64 to accept little or "native" (also little) endian operations only. Compilation of a big-endian operation will now result in a compilation error because no ISLE rule will match (no lowering exists). At some later point we could add these lowerings, but for now we at least do not miscompile. Fixes #10861.
1 parent 90a2351 commit 84477fc

File tree

10 files changed

+1049
-168
lines changed

10 files changed

+1049
-168
lines changed

cranelift/codegen/src/isa/aarch64/lower.isle

Lines changed: 64 additions & 64 deletions
Large diffs are not rendered by default.

cranelift/codegen/src/isa/riscv64/inst.isle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2450,7 +2450,7 @@
24502450
(decl sinkable_load (Inst Type MemFlags Value Offset32) Value)
24512451
(extractor (sinkable_load inst ty flags addr offset)
24522452
(and
2453-
(load flags addr offset)
2453+
(load (little_or_native_endian flags) addr offset)
24542454
(sinkable_inst (has_type ty inst))))
24552455

24562456
;; Returns a canonical type for a LoadOP. We only return I64 or F64.

cranelift/codegen/src/isa/riscv64/lower.isle

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1639,34 +1639,34 @@
16391639
(rule -1
16401640
;;
16411641
(lower
1642-
(has_type (valid_atomic_transaction ty) (atomic_rmw flags op addr x)))
1642+
(has_type (valid_atomic_transaction ty) (atomic_rmw (little_or_native_endian flags) op addr x)))
16431643
(gen_atomic (get_atomic_rmw_op ty op) addr x (atomic_amo)))
16441644

16451645
;;; for I8 and I16
16461646
(rule 1
16471647
(lower
1648-
(has_type (valid_atomic_transaction (fits_in_16 ty)) (atomic_rmw flags op addr x)))
1648+
(has_type (valid_atomic_transaction (fits_in_16 ty)) (atomic_rmw (little_or_native_endian flags) op addr x)))
16491649
(gen_atomic_rmw_loop op ty addr x))
16501650

16511651
;;;special for I8 and I16 max min etc.
16521652
;;;because I need uextend or sextend the value.
16531653
(rule 2
16541654
(lower
1655-
(has_type (valid_atomic_transaction (fits_in_16 ty)) (atomic_rmw flags (is_atomic_rmw_max_etc op true) addr x)))
1655+
(has_type (valid_atomic_transaction (fits_in_16 ty)) (atomic_rmw (little_or_native_endian flags) (is_atomic_rmw_max_etc op true) addr x)))
16561656
(gen_atomic_rmw_loop op ty addr (sext x)))
16571657

16581658

16591659
(rule 2
16601660
;;
16611661
(lower
1662-
(has_type (valid_atomic_transaction (fits_in_16 ty)) (atomic_rmw flags (is_atomic_rmw_max_etc op false) addr x)))
1662+
(has_type (valid_atomic_transaction (fits_in_16 ty)) (atomic_rmw (little_or_native_endian flags) (is_atomic_rmw_max_etc op false) addr x)))
16631663
;;
16641664
(gen_atomic_rmw_loop op ty addr (zext x)))
16651665

16661666
;;;;; Rules for `AtomicRmwOp.Sub`
16671667
(rule
16681668
(lower
1669-
(has_type (valid_atomic_transaction ty) (atomic_rmw flags (AtomicRmwOp.Sub) addr x)))
1669+
(has_type (valid_atomic_transaction ty) (atomic_rmw (little_or_native_endian flags) (AtomicRmwOp.Sub) addr x)))
16701670
(let
16711671
((tmp WritableReg (temp_writable_reg ty))
16721672
(x2 Reg (rv_neg x)))
@@ -1684,21 +1684,21 @@
16841684
;;;;; Rules for `AtomicRmwOp.Nand`
16851685
(rule
16861686
(lower
1687-
(has_type (valid_atomic_transaction ty) (atomic_rmw flags (AtomicRmwOp.Nand) addr x)))
1687+
(has_type (valid_atomic_transaction ty) (atomic_rmw (little_or_native_endian flags) (AtomicRmwOp.Nand) addr x)))
16881688
(gen_atomic_rmw_loop (AtomicRmwOp.Nand) ty addr x))
16891689

16901690
(decl is_atomic_rmw_max_etc (AtomicRmwOp bool) AtomicRmwOp)
16911691
(extern extractor is_atomic_rmw_max_etc is_atomic_rmw_max_etc)
16921692

16931693
;;;;; Rules for `atomic load`;;;;;;;;;;;;;;;;;
16941694
(rule
1695-
(lower (has_type (valid_atomic_transaction ty) (atomic_load flags p)))
1695+
(lower (has_type (valid_atomic_transaction ty) (atomic_load (little_or_native_endian flags) p)))
16961696
(gen_atomic_load p ty))
16971697

16981698

16991699
;;;;; Rules for `atomic store`;;;;;;;;;;;;;;;;;
17001700
(rule
1701-
(lower (atomic_store flags src @ (value_type (valid_atomic_transaction ty)) p))
1701+
(lower (atomic_store (little_or_native_endian flags) src @ (value_type (valid_atomic_transaction ty)) p))
17021702
(gen_atomic_store p ty src))
17031703

17041704
(decl gen_atomic_offset (XReg Type) XReg)
@@ -1718,7 +1718,7 @@
17181718

17191719
;;;;; Rules for `atomic cas`;;;;;;;;;;;;;;;;;
17201720
(rule
1721-
(lower (has_type (valid_atomic_transaction ty) (atomic_cas flags p e x)))
1721+
(lower (has_type (valid_atomic_transaction ty) (atomic_cas (little_or_native_endian flags) p e x)))
17221722
(let
17231723
((t0 WritableReg (temp_writable_reg ty))
17241724
(dst WritableReg (temp_writable_reg ty))
@@ -2105,40 +2105,40 @@
21052105
(gen_trapif cc x y code))
21062106

21072107
;;;;; Rules for `uload8`;;;;;;;;;
2108-
(rule (lower (uload8 flags addr offset))
2108+
(rule (lower (uload8 (little_or_native_endian flags) addr offset))
21092109
(gen_load (amode addr offset) (LoadOP.Lbu) flags))
21102110

21112111
;;;;; Rules for `sload8`;;;;;;;;;
2112-
(rule (lower (sload8 flags addr offset))
2112+
(rule (lower (sload8 (little_or_native_endian flags) addr offset))
21132113
(gen_load (amode addr offset) (LoadOP.Lb) flags))
21142114

21152115
;;;;; Rules for `uload16`;;;;;;;;;
2116-
(rule (lower (uload16 flags addr offset))
2116+
(rule (lower (uload16 (little_or_native_endian flags) addr offset))
21172117
(gen_load (amode addr offset) (LoadOP.Lhu) flags))
21182118

21192119
;;;;; Rules for `iload16`;;;;;;;;;
2120-
(rule (lower (sload16 flags addr offset))
2120+
(rule (lower (sload16 (little_or_native_endian flags) addr offset))
21212121
(gen_load (amode addr offset) (LoadOP.Lh) flags))
21222122

21232123
;;;;; Rules for `uload32`;;;;;;;;;
2124-
(rule (lower (uload32 flags addr offset))
2124+
(rule (lower (uload32 (little_or_native_endian flags) addr offset))
21252125
(gen_load (amode addr offset) (LoadOP.Lwu) flags))
21262126

21272127
;;;;; Rules for `sload32`;;;;;;;;;
2128-
(rule (lower (sload32 flags addr offset))
2128+
(rule (lower (sload32 (little_or_native_endian flags) addr offset))
21292129
(gen_load (amode addr offset) (LoadOP.Lw) flags))
21302130

21312131
;;;;; Rules for `load`;;;;;;;;;
2132-
(rule (lower (has_type ty (load flags addr offset)))
2132+
(rule (lower (has_type ty (load (little_or_native_endian flags) addr offset)))
21332133
(gen_load (amode addr offset) (load_op ty) flags))
21342134

2135-
(rule 1 (lower (has_type (ty_reg_pair _) (load flags addr offset)))
2135+
(rule 1 (lower (has_type (ty_reg_pair _) (load (little_or_native_endian flags) addr offset)))
21362136
(if-let offset_plus_8 (s32_add_fallible offset 8))
21372137
(let ((lo XReg (gen_load (amode addr offset) (LoadOP.Ld) flags))
21382138
(hi XReg (gen_load (amode addr offset_plus_8) (LoadOP.Ld) flags)))
21392139
(value_regs lo hi)))
21402140

2141-
(rule 2 (lower (has_type (ty_supported_vec ty) (load flags addr offset)))
2141+
(rule 2 (lower (has_type (ty_supported_vec ty) (load (little_or_native_endian flags) addr offset)))
21422142
(let ((eew VecElementWidth (element_width_from_type ty))
21432143
(amode AMode (amode addr offset)))
21442144
(vec_load eew (VecAMode.UnitStride amode) flags (unmasked) ty)))
@@ -2165,58 +2165,59 @@
21652165
(rv_vzext_vf2 loaded (unmasked) ty)))
21662166

21672167
;;;;; Rules for `uload8x8`;;;;;;;;;;
2168-
(rule (lower (has_type (ty_supported_vec ty @ $I16X8) (uload8x8 flags addr offset)))
2168+
(rule (lower (has_type (ty_supported_vec ty @ $I16X8) (uload8x8 (little_or_native_endian flags) addr offset)))
21692169
(gen_load64_extend ty (ExtendOp.Zero) flags (amode addr offset)))
21702170

21712171
;;;;; Rules for `uload16x4`;;;;;;;;;
2172-
(rule (lower (has_type (ty_supported_vec ty @ $I32X4) (uload16x4 flags addr offset)))
2172+
(rule (lower (has_type (ty_supported_vec ty @ $I32X4) (uload16x4 (little_or_native_endian flags) addr offset)))
21732173
(gen_load64_extend ty (ExtendOp.Zero) flags (amode addr offset)))
21742174

21752175
;;;;; Rules for `uload32x2`;;;;;;;;;
2176-
(rule (lower (has_type (ty_supported_vec ty @ $I64X2) (uload32x2 flags addr offset)))
2176+
(rule (lower (has_type (ty_supported_vec ty @ $I64X2) (uload32x2 (little_or_native_endian flags) addr offset)))
21772177
(gen_load64_extend ty (ExtendOp.Zero) flags (amode addr offset)))
21782178

21792179
;;;;; Rules for `sload8x8`;;;;;;;;;;
2180-
(rule (lower (has_type (ty_supported_vec ty @ $I16X8) (sload8x8 flags addr offset)))
2180+
(rule (lower (has_type (ty_supported_vec ty @ $I16X8) (sload8x8 (little_or_native_endian flags) addr offset)))
21812181
(gen_load64_extend ty (ExtendOp.Signed) flags (amode addr offset)))
21822182

21832183
;;;;; Rules for `sload16x4`;;;;;;;;;
2184-
(rule (lower (has_type (ty_supported_vec ty @ $I32X4) (sload16x4 flags addr offset)))
2184+
(rule (lower (has_type (ty_supported_vec ty @ $I32X4) (sload16x4 (little_or_native_endian flags) addr offset)))
21852185
(gen_load64_extend ty (ExtendOp.Signed) flags (amode addr offset)))
21862186

21872187
;;;;; Rules for `sload32x2`;;;;;;;;;
2188-
(rule (lower (has_type (ty_supported_vec ty @ $I64X2) (sload32x2 flags addr offset)))
2188+
(rule (lower (has_type (ty_supported_vec ty @ $I64X2) (sload32x2 (little_or_native_endian flags) addr offset)))
21892189
(gen_load64_extend ty (ExtendOp.Signed) flags (amode addr offset)))
21902190

21912191
;;;;; Rules for `istore8`;;;;;;;;;
2192-
(rule (lower (istore8 flags src addr offset))
2192+
(rule (lower (istore8 (little_or_native_endian flags) src addr offset))
21932193
(rv_store (amode addr offset) (StoreOP.Sb) flags src))
21942194

21952195
;;;;; Rules for `istore16`;;;;;;;;;
2196-
(rule (lower (istore16 flags src addr offset))
2196+
(rule (lower (istore16 (little_or_native_endian flags) src addr offset))
21972197
(rv_store (amode addr offset) (StoreOP.Sh) flags src))
21982198

21992199
;;;;; Rules for `istore32`;;;;;;;;;
2200-
(rule (lower (istore32 flags src addr offset))
2200+
(rule (lower (istore32 (little_or_native_endian flags) src addr offset))
22012201
(rv_store (amode addr offset) (StoreOP.Sw) flags src))
22022202

22032203
;;;;; Rules for `store`;;;;;;;;;
2204-
(rule (lower (store flags src @ (value_type ty) addr offset))
2204+
(rule (lower (store (little_or_native_endian flags) src @ (value_type ty) addr offset))
22052205
(gen_store (amode addr offset) flags src))
22062206

2207-
(rule 1 (lower (store flags src @ (value_type (ty_reg_pair _)) addr offset))
2207+
(rule 1 (lower (store (little_or_native_endian flags) src @ (value_type (ty_reg_pair _)) addr offset))
22082208
(if-let offset_plus_8 (s32_add_fallible offset 8))
22092209
(let ((_ InstOutput (rv_store (amode addr offset) (StoreOP.Sd) flags (value_regs_get src 0))))
22102210
(rv_store (amode addr offset_plus_8) (StoreOP.Sd) flags (value_regs_get src 1))))
22112211

2212-
(rule 2 (lower (store flags src @ (value_type (ty_supported_vec ty)) addr offset))
2212+
(rule 2 (lower (store (little_or_native_endian flags) src @ (value_type (ty_supported_vec ty)) addr offset))
22132213
(let ((eew VecElementWidth (element_width_from_type ty))
22142214
(amode AMode (amode addr offset)))
22152215
(vec_store eew (VecAMode.UnitStride amode) src flags (unmasked) ty)))
22162216

22172217
;; Avoid unnecessary moves to floating point registers for `F16` memory to memory copies when
22182218
;; `Zfhmin` is unavailable.
2219-
(rule 3 (lower (store store_flags (sinkable_load inst $F16 load_flags load_addr load_offset) store_addr store_offset))
2219+
(rule 3 (lower (store (little_or_native_endian store_flags)
2220+
(sinkable_load inst $F16 (little_or_native_endian load_flags) load_addr load_offset) store_addr store_offset))
22202221
(if-let false (has_zfhmin))
22212222
(rv_store (amode store_addr store_offset) (StoreOP.Sh) store_flags (gen_sunk_load inst (amode load_addr load_offset) (LoadOP.Lh) load_flags)))
22222223

0 commit comments

Comments
 (0)