Legalize load.i128 and store.i128 with arbitrary offsets

This commit is contained in:
bjorn3
2019-07-18 12:54:59 +02:00
committed by Dan Gohman
parent 67593d997b
commit acd454890c
2 changed files with 67 additions and 7 deletions

View File

@@ -567,3 +567,63 @@ fn expand_stack_store(
mflags.set_aligned(); mflags.set_aligned();
pos.func.dfg.replace(inst).store(mflags, val, addr, 0); pos.func.dfg.replace(inst).store(mflags, val, addr, 0);
} }
/// Split a load into two parts before `iconcat`ing the result together.
fn narrow_load(
inst: ir::Inst,
func: &mut ir::Function,
_cfg: &mut ControlFlowGraph,
_isa: &dyn TargetIsa,
) {
let mut pos = FuncCursor::new(func).at_inst(inst);
pos.use_srcloc(inst);
let (ptr, offset, flags) = match pos.func.dfg[inst] {
ir::InstructionData::Load {
opcode: ir::Opcode::Load,
arg,
offset,
flags,
} => (arg, offset, flags),
_ => panic!("Expected load: {}", pos.func.dfg.display_inst(inst, None)),
};
let al = pos.ins().load(ir::types::I64, flags, ptr, offset);
let ah = pos.ins().load(
ir::types::I64,
flags,
ptr,
offset.try_add_i64(8).expect("load offset overflow"),
);
pos.func.dfg.replace(inst).iconcat(al, ah);
}
/// Split a store into two parts after `isplit`ing the value.
fn narrow_store(
inst: ir::Inst,
func: &mut ir::Function,
_cfg: &mut ControlFlowGraph,
_isa: &dyn TargetIsa,
) {
let mut pos = FuncCursor::new(func).at_inst(inst);
pos.use_srcloc(inst);
let (val, ptr, offset, flags) = match pos.func.dfg[inst] {
ir::InstructionData::Store {
opcode: ir::Opcode::Store,
args,
offset,
flags,
} => (args[0], args[1], offset, flags),
_ => panic!("Expected store: {}", pos.func.dfg.display_inst(inst, None)),
};
let (al, ah) = pos.func.dfg.replace(inst).isplit(val);
pos.ins().store(flags, al, ptr, offset);
pos.ins().store(
flags,
ah,
ptr,
offset.try_add_i64(8).expect("store offset overflow"),
);
}

View File

@@ -28,19 +28,19 @@ ebb0(v0: i128):
} }
function u0:2(i64, i128) fast { function u0:2(i64, i128) fast {
; check: ebb0(v0: i64 [%rdi], v2: i64 [%rsi], v3: i64 [%rdx], v4: i64 [%rbp]): ; check: ebb0(v0: i64 [%rdi], v2: i64 [%rsi], v3: i64 [%rdx], v6: i64 [%rbp]):
ebb0(v0: i64, v1: i128): ebb0(v0: i64, v1: i128):
; check: store v2, v0 ; check: store v2, v0+8
; check: store v3, v0+8 ; check: store v3, v0+16
store v1, v0 store v1, v0+8
return return
} }
function u0:3(i64) -> i128 fast { function u0:3(i64) -> i128 fast {
ebb0(v0: i64): ebb0(v0: i64):
; check: v2 = load.i64 v0 ; check: v2 = load.i64 v0+8
; check: v3 = load.i64 v0+8 ; check: v3 = load.i64 v0+16
v1 = load.i128 v0 v1 = load.i128 v0+8
; check: return v2, v3, v5 ; check: return v2, v3, v5
return v1 return v1
} }