Zero-extend the result of extractlane

Previously, `extractlane` results did not have the expected `uextend` because this work was completed by PEXTRB in x86. Since other architectures may eventually need this and since leaving the `uextend` out leaves the extracted values with the wrong type (`i16` instead of `i32`), the `uextend` is re-added. The duplicated zero-extension work (from PEXTRB and MOVZX) could be fixed by a later optimization.
This commit is contained in:
Andrew Brown
2020-03-20 18:56:06 -07:00
parent 65856987cd
commit 39c0a28d77

View File

@@ -1282,8 +1282,11 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
} }
Operator::I8x16ExtractLaneU { lane } | Operator::I16x8ExtractLaneU { lane } => { Operator::I8x16ExtractLaneU { lane } | Operator::I16x8ExtractLaneU { lane } => {
let vector = pop1_with_bitcast(state, type_of(op), builder); let vector = pop1_with_bitcast(state, type_of(op), builder);
state.push1(builder.ins().extractlane(vector, lane.clone())); let extracted = builder.ins().extractlane(vector, lane.clone());
// on x86, PEXTRB zeroes the upper bits of the destination register of extractlane so uextend is elided; of course, this depends on extractlane being legalized to a PEXTRB state.push1(builder.ins().uextend(I32, extracted));
// On x86, PEXTRB zeroes the upper bits of the destination register of extractlane so
// uextend could be elided; for now, uextend is needed for Cranelift's type checks to
// work.
} }
Operator::I32x4ExtractLane { lane } Operator::I32x4ExtractLane { lane }
| Operator::I64x2ExtractLane { lane } | Operator::I64x2ExtractLane { lane }