Skip to content

Commit cf68342

Browse files
authored
Unrolled build for #160441
Rollup merge of #160441 - beetrees:inline-asm-fix-powerpc64le, r=Amanieu PowerPC inline ASM: Fix scalar floats being in the wrong vector lane on little endian 64-bit PowerPC supports both big and little endian, however registers are always big endian. As a consequence of this, the order of vector lanes is reversed on little endian; however scalar `f32` and `f64` are always stored in the actual (big-endian) lane 0. This PR fixes the LLVM ASM fixup to take that into account. Ping target maintainers: @daltenty @gilamn5tr @amy-kwan @Gelbpunkt @famfo @neuschaefer
2 parents a9066b3 + 325add2 commit cf68342

2 files changed

Lines changed: 282 additions & 430 deletions

File tree

compiler/rustc_codegen_llvm/src/asm.rs

Lines changed: 23 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::assert_matches;
22
use std::fmt::Write;
33

4-
use rustc_abi::{BackendRepr, Float, Integer, Primitive, Scalar, Size};
4+
use rustc_abi::{BackendRepr, Endian, Float, Integer, Primitive, Scalar, Size};
55
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
66
use rustc_codegen_ssa::mir::operand::OperandValue;
77
use rustc_codegen_ssa::traits::*;
@@ -12,6 +12,7 @@ use rustc_middle::ty::layout::TyAndLayout;
1212
use rustc_middle::{bug, span_bug};
1313
use rustc_span::{Pos, Span, Symbol, sym};
1414
use rustc_target::asm::*;
15+
use rustc_target::spec::HasTargetSpec;
1516
use smallvec::SmallVec;
1617
use tracing::debug;
1718

@@ -1244,24 +1245,16 @@ fn llvm_fixup_input<'ll, 'tcx>(
12441245
(
12451246
PowerPC(PowerPCInlineAsmRegClass::vreg | PowerPCInlineAsmRegClass::vsreg),
12461247
BackendRepr::Scalar(s),
1247-
) if s.primitive() == Primitive::Float(Float::F32) => {
1248-
let value = bx.insert_element(
1249-
bx.const_undef(bx.type_vector(bx.type_f32(), 4)),
1248+
) if let Primitive::Float(float @ (Float::F32 | Float::F64)) = s.primitive() => {
1249+
let num_lanes = 16 / float.size().bytes();
1250+
bx.insert_element(
1251+
bx.const_undef(bx.type_vector(bx.type_from_float(float), num_lanes)),
12501252
value,
1251-
bx.const_usize(0),
1252-
);
1253-
bx.bitcast(value, bx.type_vector(bx.type_f32(), 4))
1254-
}
1255-
(
1256-
PowerPC(PowerPCInlineAsmRegClass::vreg | PowerPCInlineAsmRegClass::vsreg),
1257-
BackendRepr::Scalar(s),
1258-
) if s.primitive() == Primitive::Float(Float::F64) => {
1259-
let value = bx.insert_element(
1260-
bx.const_undef(bx.type_vector(bx.type_f64(), 2)),
1261-
value,
1262-
bx.const_usize(0),
1263-
);
1264-
bx.bitcast(value, bx.type_vector(bx.type_f64(), 2))
1253+
bx.const_usize(match bx.target_spec().endian {
1254+
Endian::Little => num_lanes - 1,
1255+
Endian::Big => 0,
1256+
}),
1257+
)
12651258
}
12661259
_ => value,
12671260
}
@@ -1416,16 +1409,15 @@ fn llvm_fixup_output<'ll, 'tcx>(
14161409
(
14171410
PowerPC(PowerPCInlineAsmRegClass::vreg | PowerPCInlineAsmRegClass::vsreg),
14181411
BackendRepr::Scalar(s),
1419-
) if s.primitive() == Primitive::Float(Float::F32) => {
1420-
let value = bx.bitcast(value, bx.type_vector(bx.type_f32(), 4));
1421-
bx.extract_element(value, bx.const_usize(0))
1422-
}
1423-
(
1424-
PowerPC(PowerPCInlineAsmRegClass::vreg | PowerPCInlineAsmRegClass::vsreg),
1425-
BackendRepr::Scalar(s),
1426-
) if s.primitive() == Primitive::Float(Float::F64) => {
1427-
let value = bx.bitcast(value, bx.type_vector(bx.type_f64(), 2));
1428-
bx.extract_element(value, bx.const_usize(0))
1412+
) if let Primitive::Float(float @ (Float::F32 | Float::F64)) = s.primitive() => {
1413+
let num_lanes = 16 / float.size().bytes();
1414+
bx.extract_element(
1415+
value,
1416+
bx.const_usize(match bx.target_spec().endian {
1417+
Endian::Little => num_lanes - 1,
1418+
Endian::Big => 0,
1419+
}),
1420+
)
14291421
}
14301422
_ => value,
14311423
}
@@ -1566,11 +1558,9 @@ fn llvm_fixup_output_type<'ll, 'tcx>(
15661558
(
15671559
PowerPC(PowerPCInlineAsmRegClass::vreg | PowerPCInlineAsmRegClass::vsreg),
15681560
BackendRepr::Scalar(s),
1569-
) if s.primitive() == Primitive::Float(Float::F32) => cx.type_vector(cx.type_f32(), 4),
1570-
(
1571-
PowerPC(PowerPCInlineAsmRegClass::vreg | PowerPCInlineAsmRegClass::vsreg),
1572-
BackendRepr::Scalar(s),
1573-
) if s.primitive() == Primitive::Float(Float::F64) => cx.type_vector(cx.type_f64(), 2),
1561+
) if let Primitive::Float(float @ (Float::F32 | Float::F64)) = s.primitive() => {
1562+
cx.type_vector(cx.type_from_float(float), 16 / float.size().bytes())
1563+
}
15741564
_ => layout.llvm_type(cx),
15751565
}
15761566
}

0 commit comments

Comments
 (0)