Auto merge of #51583 - cuviper:packed_pair-bool, r=Mark-Simulacrum

Store scalar pair bools as i8 in memory

We represent `bool` as `i1` in a `ScalarPair`, unlike other aggregates,
to optimize IR for checked operators and the like.  With this patch, we
still do so when the pair is an immediate value, but we use the `i8`
memory type when the value is loaded or stored as an LLVM aggregate.

So `(bool, bool)` looks like an `{ i1, i1 }` immediate, but `{ i8, i8 }`
in memory.  When a pair is a direct function argument, `PassMode::Pair`,
it is still passed using the immediate `i1` type, but as a return value
it will use the `i8` memory type.  Also, `bool`-like` enum tags will now
use scalar pairs when possible, where they were previously excluded due
to optimization issues.

Fixes #51516.
Closes #51566.

r? @eddyb
cc @nox
This commit is contained in:
bors 2018-07-10 03:08:47 +00:00
commit b3e7d70ce7
9 changed files with 96 additions and 50 deletions

View file

@ -266,8 +266,8 @@ pub fn unsize_thin_ptr<'a, 'tcx>(
}
let (lldata, llextra) = result.unwrap();
// HACK(eddyb) have to bitcast pointers until LLVM removes pointee types.
(bx.bitcast(lldata, dst_layout.scalar_pair_element_llvm_type(bx.cx, 0)),
bx.bitcast(llextra, dst_layout.scalar_pair_element_llvm_type(bx.cx, 1)))
(bx.bitcast(lldata, dst_layout.scalar_pair_element_llvm_type(bx.cx, 0, true)),
bx.bitcast(llextra, dst_layout.scalar_pair_element_llvm_type(bx.cx, 1, true)))
}
_ => bug!("unsize_thin_ptr: called on bad types"),
}
@ -397,9 +397,14 @@ pub fn from_immediate(bx: &Builder, val: ValueRef) -> ValueRef {
pub fn to_immediate(bx: &Builder, val: ValueRef, layout: layout::TyLayout) -> ValueRef {
if let layout::Abi::Scalar(ref scalar) = layout.abi {
if scalar.is_bool() {
return bx.trunc(val, Type::i1(bx.cx));
}
return to_immediate_scalar(bx, val, scalar);
}
val
}
pub fn to_immediate_scalar(bx: &Builder, val: ValueRef, scalar: &layout::Scalar) -> ValueRef {
if scalar.is_bool() {
return bx.trunc(val, Type::i1(bx.cx));
}
val
}