Skip to content
This repository was archived by the owner on Jun 26, 2020. It is now read-only.

Commit b5396fe

Browse files
committed
Legalize load.i128 and store.i128 with arbitrary offsets
1 parent d4eaf31 commit b5396fe

File tree

3 files changed

+69
-31
lines changed

3 files changed

+69
-31
lines changed

cranelift-codegen/meta/src/shared/legalize.rs

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,6 @@ pub fn define(insts: &InstructionGroup, immediates: &OperandKinds) -> TransformG
148148
let ieee32 = immediates.by_name("ieee32");
149149
let ieee64 = immediates.by_name("ieee64");
150150
let intcc = immediates.by_name("intcc");
151-
let offset32 = immediates.by_name("offset32");
152151

153152
// List of variables to reuse in patterns.
154153
let x = var("x");
@@ -287,29 +286,8 @@ pub fn define(insts: &InstructionGroup, immediates: &OperandKinds) -> TransformG
287286
],
288287
);
289288

290-
// FIXME generalize to any offset once offset+8 can be represented
291-
narrow.legalize(
292-
def!(a = load.I128(flags, ptr, Literal::constant(offset32, 0))),
293-
vec![
294-
def!(al = load.I64(flags, ptr, Literal::constant(offset32, 0))),
295-
def!(ah = load.I64(flags, ptr, Literal::constant(offset32, 8))),
296-
// `iconcat` expects the same byte order as stored in memory,
297-
// so no need to swap depending on endianness.
298-
def!(a = iconcat(al, ah)),
299-
],
300-
);
301-
302-
// FIXME generalize to any offset once offset+8 can be represented
303-
narrow.legalize(
304-
def!(store.I128(flags, a, ptr, Literal::constant(offset32, 0))),
305-
vec![
306-
// `isplit` gives the same byte order as stored in memory,
307-
// so no need to swap depending on endianness.
308-
def!((al, ah) = isplit(a)),
309-
def!(store.I64(flags, al, ptr, Literal::constant(offset32, 0))),
310-
def!(store.I64(flags, ah, ptr, Literal::constant(offset32, 8))),
311-
],
312-
);
289+
narrow.custom_legalize(load, "narrow_load");
290+
narrow.custom_legalize(store, "narrow_store");
313291

314292
// Widen instructions with one input operand.
315293
for &op in &[bnot, popcnt] {

cranelift-codegen/src/legalizer/mod.rs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,3 +559,63 @@ fn expand_stack_store(
559559
mflags.set_aligned();
560560
pos.func.dfg.replace(inst).store(mflags, val, addr, 0);
561561
}
562+
563+
/// Split a load into two parts before `iconcat`ing the result together.
564+
fn narrow_load(
565+
inst: ir::Inst,
566+
func: &mut ir::Function,
567+
_cfg: &mut ControlFlowGraph,
568+
_isa: &dyn TargetIsa,
569+
) {
570+
let mut pos = FuncCursor::new(func).at_inst(inst);
571+
pos.use_srcloc(inst);
572+
573+
let (ptr, offset, flags) = match pos.func.dfg[inst] {
574+
ir::InstructionData::Load {
575+
opcode: ir::Opcode::Load,
576+
arg,
577+
offset,
578+
flags,
579+
} => (arg, offset, flags),
580+
_ => panic!("Expected load: {}", pos.func.dfg.display_inst(inst, None)),
581+
};
582+
583+
let al = pos.ins().load(ir::types::I64, flags, ptr, offset);
584+
let ah = pos.ins().load(
585+
ir::types::I64,
586+
flags,
587+
ptr,
588+
offset.try_add_i64(8).expect("load offset overflow"),
589+
);
590+
pos.func.dfg.replace(inst).iconcat(al, ah);
591+
}
592+
593+
/// Split a store into two parts after `isplit`ing the value.
594+
fn narrow_store(
595+
inst: ir::Inst,
596+
func: &mut ir::Function,
597+
_cfg: &mut ControlFlowGraph,
598+
_isa: &dyn TargetIsa,
599+
) {
600+
let mut pos = FuncCursor::new(func).at_inst(inst);
601+
pos.use_srcloc(inst);
602+
603+
let (val, ptr, offset, flags) = match pos.func.dfg[inst] {
604+
ir::InstructionData::Store {
605+
opcode: ir::Opcode::Store,
606+
args,
607+
offset,
608+
flags,
609+
} => (args[0], args[1], offset, flags),
610+
_ => panic!("Expected store: {}", pos.func.dfg.display_inst(inst, None)),
611+
};
612+
613+
let (al, ah) = pos.func.dfg.replace(inst).isplit(val);
614+
pos.ins().store(flags, al, ptr, offset);
615+
pos.ins().store(
616+
flags,
617+
ah,
618+
ptr,
619+
offset.try_add_i64(8).expect("store offset overflow"),
620+
);
621+
}

filetests/isa/x86/i128.clif

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,19 @@ ebb0(v0: i128):
2828
}
2929

3030
function u0:2(i64, i128) fast {
31-
; check: ebb0(v0: i64 [%rdi], v2: i64 [%rsi], v3: i64 [%rdx], v4: i64 [%rbp]):
31+
; check: ebb0(v0: i64 [%rdi], v2: i64 [%rsi], v3: i64 [%rdx], v6: i64 [%rbp]):
3232
ebb0(v0: i64, v1: i128):
33-
; check: store v2, v0
34-
; check: store v3, v0+8
35-
store v1, v0
33+
; check: store v2, v0+8
34+
; check: store v3, v0+16
35+
store v1, v0+8
3636
return
3737
}
3838

3939
function u0:3(i64) -> i128 fast {
4040
ebb0(v0: i64):
41-
; check: v2 = load.i64 v0
42-
; check: v3 = load.i64 v0+8
43-
v1 = load.i128 v0
41+
; check: v2 = load.i64 v0+8
42+
; check: v3 = load.i64 v0+16
43+
v1 = load.i128 v0+8
4444
; check: return v2, v3, v5
4545
return v1
4646
}

0 commit comments

Comments
 (0)