Skip to content

Commit 352a184

Browse files
committed
Load enum with specific ranges
1 parent 490b2cc commit 352a184

File tree

1 file changed

+41
-1
lines changed

1 file changed

+41
-1
lines changed

compiler/rustc_codegen_llvm/src/builder.rs

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -505,7 +505,47 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
505505

506506
match scalar.primitive() {
507507
abi::Primitive::Int(..) => {
508-
if !scalar.is_always_valid(bx) {
508+
if let Some(adt) = layout.ty.ty_adt_def()
509+
&& adt.is_enum()
510+
{
511+
let mut discr_vals: Vec<_> =
512+
adt.discriminants(bx.tcx).map(|(_, d)| d.val).collect();
513+
discr_vals.sort();
514+
let mut ranges =
515+
vec![WrappingRange { start: discr_vals[0], end: discr_vals[0] }];
516+
for &discr in &discr_vals[1..] {
517+
let last = ranges.last_mut().unwrap();
518+
if discr == last.end + 1 {
519+
last.end = discr;
520+
} else if !last.contains(discr) {
521+
ranges.push(WrappingRange { start: discr, end: discr });
522+
}
523+
}
524+
525+
if bx.cx.sess().opts.optimize != OptLevel::No {
526+
unsafe {
527+
let llty = bx.cx.val_ty(load);
528+
let md =
529+
ranges
530+
.iter()
531+
.flat_map(|range| {
532+
[
533+
llvm::LLVMValueAsMetadata(
534+
bx.cx.const_uint_big(llty, range.start),
535+
),
536+
llvm::LLVMValueAsMetadata(bx.cx.const_uint_big(
537+
llty,
538+
range.end.wrapping_add(1),
539+
)),
540+
]
541+
})
542+
.collect::<Vec<_>>();
543+
let md =
544+
llvm::LLVMMDNodeInContext2(bx.cx.llcx, md.as_ptr(), md.len());
545+
bx.set_metadata(load, llvm::MD_range, md);
546+
}
547+
}
548+
} else if !scalar.is_always_valid(bx) {
509549
bx.range_metadata(load, scalar.valid_range(bx));
510550
}
511551
}

0 commit comments

Comments
 (0)