Skip to content

&str.slice is bloated #16625

Closed
Closed
@huonw

Description

@huonw
#![crate_type = "lib"]
pub fn slice(x: &str, a: uint, b: uint) -> &str {
    x.slice(a, b)
}

with -O becomes

; Function Attrs: uwtable
define void @_ZN5slice20ha62b7cd23f98de21daaE(%str_slice* noalias nocapture sret dereferenceable(16), %str_slice* noalias nocapture dereferenceable(16), i64, i64) unnamed_addr #0 {
entry-block:
  %4 = alloca %str_slice, align 8
  %5 = alloca %"struct.core::fmt::Argument<[]>[#3]", align 8
  %__args.i.i = alloca %"struct.core::fmt::Arguments<[]>[#3]", align 8
  %6 = alloca %str_slice, align 8
  %7 = alloca %"struct.core::fmt::Argument<[]>[#3]", align 8
  %__args7.i.i = alloca %"struct.core::fmt::Arguments<[]>[#3]", align 8
  %begin.i = alloca i64, align 8
  %end.i = alloca i64, align 8
  %8 = alloca [3 x %"struct.core::fmt::Argument<[]>[#3]"], align 8
  %__args.i = alloca %"struct.core::fmt::Arguments<[]>[#3]", align 8
  %.sub.i = getelementptr inbounds [3 x %"struct.core::fmt::Argument<[]>[#3]"]* %8, i64 0, i64 0
  %9 = bitcast i64* %begin.i to i8*
  call void @llvm.lifetime.start(i64 8, i8* %9)
  store i64 %2, i64* %begin.i, align 8
  %10 = bitcast i64* %end.i to i8*
  call void @llvm.lifetime.start(i64 8, i8* %10)
  store i64 %3, i64* %end.i, align 8
  %.sroa.3.0..sroa_idx4.i.i.i = getelementptr inbounds %str_slice* %1, i64 0, i32 1
  %.sroa.3.0.copyload.i.i.i = load i64* %.sroa.3.0..sroa_idx4.i.i.i, align 8
  %11 = icmp eq i64 %.sroa.3.0.copyload.i.i.i, %2
  br i1 %11, label %before_rhs.i, label %next-block.i.i

next-block.i.i:                                   ; preds = %entry-block
  %12 = icmp ult i64 %.sroa.3.0.copyload.i.i.i, %2
  br i1 %12, label %then-block-54-.i, label %next-block1.i.i

next-block1.i.i:                                  ; preds = %next-block.i.i
  %13 = icmp ugt i64 %.sroa.3.0.copyload.i.i.i, %2
  br i1 %13, label %"_ZN3str39_$BP$$x27a$x20str.StrSlice$LT$$x27a$GT$16is_char_boundary20h77e6472c98e21760edaE.exit.i", label %cond.i.i, !prof !0

cond.i.i:                                         ; preds = %next-block1.i.i
  tail call void @_ZN7failure17fail_bounds_check20hb6567e7af36a3c08KykE({ %str_slice, i64 }* noalias nocapture readonly dereferenceable(24) @const, i64 %2, i64 %.sroa.3.0.copyload.i.i.i)
  unreachable

"_ZN3str39_$BP$$x27a$x20str.StrSlice$LT$$x27a$GT$16is_char_boundary20h77e6472c98e21760edaE.exit.i": ; preds = %next-block1.i.i
  %.sroa.0.0..sroa_idx.i.i = getelementptr inbounds %str_slice* %1, i64 0, i32 0
  %.sroa.0.0.copyload.i.i = load i8** %.sroa.0.0..sroa_idx.i.i, align 8
  %14 = getelementptr inbounds i8* %.sroa.0.0.copyload.i.i, i64 %2
  %15 = load i8* %14, align 1
  %16 = icmp sgt i8 %15, -1
  %17 = icmp ugt i8 %15, -65
  %..i.i = or i1 %16, %17
  br i1 %..i.i, label %before_rhs.i, label %then-block-54-.i

join.i:                                           ; preds = %next-block1.i15.i
  %.sroa.0.0..sroa_idx.i16.i = getelementptr inbounds %str_slice* %1, i64 0, i32 0
  %.sroa.0.0.copyload.i17.i = load i8** %.sroa.0.0..sroa_idx.i16.i, align 8
  %18 = getelementptr inbounds i8* %.sroa.0.0.copyload.i17.i, i64 %3
  %19 = load i8* %18, align 1
  %20 = icmp sgt i8 %19, -1
  %21 = icmp ugt i8 %19, -65
  %..i18.i = or i1 %20, %21
  br i1 %..i18.i, label %next-block.i, label %then-block-54-.i

before_rhs.i:                                     ; preds = %"_ZN3str39_$BP$$x27a$x20str.StrSlice$LT$$x27a$GT$16is_char_boundary20h77e6472c98e21760edaE.exit.i", %entry-block
  %22 = icmp eq i64 %.sroa.3.0.copyload.i.i.i, %3
  br i1 %22, label %before_rhs.next-block_crit_edge.i, label %next-block.i14.i

before_rhs.next-block_crit_edge.i:                ; preds = %before_rhs.i
  %arg.sroa.0.0..sroa_idx.phi.trans.insert.i = getelementptr inbounds %str_slice* %1, i64 0, i32 0
  %arg.sroa.0.0.copyload.pre.i = load i8** %arg.sroa.0.0..sroa_idx.phi.trans.insert.i, align 8
  br label %next-block.i

next-block.i14.i:                                 ; preds = %before_rhs.i
  %23 = icmp ult i64 %.sroa.3.0.copyload.i.i.i, %3
  br i1 %23, label %then-block-54-.i, label %next-block1.i15.i

next-block1.i15.i:                                ; preds = %next-block.i14.i
  %24 = icmp ugt i64 %.sroa.3.0.copyload.i.i.i, %3
  br i1 %24, label %join.i, label %cond.i20.i, !prof !0

cond.i20.i:                                       ; preds = %next-block1.i15.i
  tail call void @_ZN7failure17fail_bounds_check20hb6567e7af36a3c08KykE({ %str_slice, i64 }* noalias nocapture readonly dereferenceable(24) @const, i64 %3, i64 %.sroa.3.0.copyload.i.i.i)
  unreachable

then-block-54-.i:                                 ; preds = %next-block.i14.i, %join.i, %"_ZN3str39_$BP$$x27a$x20str.StrSlice$LT$$x27a$GT$16is_char_boundary20h77e6472c98e21760edaE.exit.i", %next-block.i.i
  %25 = bitcast [3 x %"struct.core::fmt::Argument<[]>[#3]"]* %8 to i8*
  call void @llvm.lifetime.start(i64 16, i8* %25)
  %26 = getelementptr inbounds [3 x %"struct.core::fmt::Argument<[]>[#3]"]* %8, i64 0, i64 0, i32 0
  store %"enum.core::result::Result<[(), core::fmt::FormatError]>[#3]" (%"enum.core::fmt::Void<[]>[#3]"*, %"struct.core::fmt::Formatter<[]>[#3]"*)* bitcast (%"enum.core::result::Result<[(), core::fmt::FormatError]>[#3]" (i64*, %"struct.core::fmt::Formatter<[]>[#3]"*)* @_ZN3fmt11secret_show20h2484714462526658409E to %"enum.core::result::Result<[(), core::fmt::FormatError]>[#3]" (%"enum.core::fmt::Void<[]>[#3]"*, %"struct.core::fmt::Formatter<[]>[#3]"*)*), %"enum.core::result::Result<[(), core::fmt::FormatError]>[#3]" (%"enum.core::fmt::Void<[]>[#3]"*, %"struct.core::fmt::Formatter<[]>[#3]"*)** %26, align 8
  %27 = getelementptr inbounds [3 x %"struct.core::fmt::Argument<[]>[#3]"]* %8, i64 0, i64 0, i32 1
  %.c.i.i = bitcast i64* %begin.i to %"enum.core::fmt::Void<[]>[#3]"*
  store %"enum.core::fmt::Void<[]>[#3]"* %.c.i.i, %"enum.core::fmt::Void<[]>[#3]"** %27, align 8
  %28 = getelementptr inbounds [3 x %"struct.core::fmt::Argument<[]>[#3]"]* %8, i64 0, i64 1, i32 0
  store %"enum.core::result::Result<[(), core::fmt::FormatError]>[#3]" (%"enum.core::fmt::Void<[]>[#3]"*, %"struct.core::fmt::Formatter<[]>[#3]"*)* bitcast (%"enum.core::result::Result<[(), core::fmt::FormatError]>[#3]" (i64*, %"struct.core::fmt::Formatter<[]>[#3]"*)* @_ZN3fmt11secret_show20h2484714462526658409E to %"enum.core::result::Result<[(), core::fmt::FormatError]>[#3]" (%"enum.core::fmt::Void<[]>[#3]"*, %"struct.core::fmt::Formatter<[]>[#3]"*)*), %"enum.core::result::Result<[(), core::fmt::FormatError]>[#3]" (%"enum.core::fmt::Void<[]>[#3]"*, %"struct.core::fmt::Formatter<[]>[#3]"*)** %28, align 8
  %29 = getelementptr inbounds [3 x %"struct.core::fmt::Argument<[]>[#3]"]* %8, i64 0, i64 1, i32 1
  %.c.i25.i = bitcast i64* %end.i to %"enum.core::fmt::Void<[]>[#3]"*
  store %"enum.core::fmt::Void<[]>[#3]"* %.c.i25.i, %"enum.core::fmt::Void<[]>[#3]"** %29, align 8
  %30 = getelementptr inbounds [3 x %"struct.core::fmt::Argument<[]>[#3]"]* %8, i64 0, i64 2, i32 0
  store %"enum.core::result::Result<[(), core::fmt::FormatError]>[#3]" (%"enum.core::fmt::Void<[]>[#3]"*, %"struct.core::fmt::Formatter<[]>[#3]"*)* bitcast (%"enum.core::result::Result<[(), core::fmt::FormatError]>[#3]" (%str_slice*, %"struct.core::fmt::Formatter<[]>[#3]"*)* @_ZN3fmt11secret_show20h1520870893265926329E to %"enum.core::result::Result<[(), core::fmt::FormatError]>[#3]" (%"enum.core::fmt::Void<[]>[#3]"*, %"struct.core::fmt::Formatter<[]>[#3]"*)*), %"enum.core::result::Result<[(), core::fmt::FormatError]>[#3]" (%"enum.core::fmt::Void<[]>[#3]"*, %"struct.core::fmt::Formatter<[]>[#3]"*)** %30, align 8
  %31 = getelementptr inbounds [3 x %"struct.core::fmt::Argument<[]>[#3]"]* %8, i64 0, i64 2, i32 1
  %.c.i26.i = bitcast %str_slice* %1 to %"enum.core::fmt::Void<[]>[#3]"*
  store %"enum.core::fmt::Void<[]>[#3]"* %.c.i26.i, %"enum.core::fmt::Void<[]>[#3]"** %31, align 8
  %32 = bitcast %"struct.core::fmt::Arguments<[]>[#3]"* %__args.i to i8*
  call void @llvm.lifetime.start(i64 32, i8* %32)
  %__adjust.sroa.0.0..sroa_idx.i = getelementptr inbounds %"struct.core::fmt::Arguments<[]>[#3]"* %__args.i, i64 0, i32 0, i32 0
  store %"enum.core::fmt::rt::Piece<[]>[#3]"* bitcast ({ { i8, %str_slice, [48 x i8] }, { i8, { { i8, [15 x i8] }, { i32, i8, i64, { i8, [15 x i8] }, { i8, [15 x i8] } } }, [0 x i8] }, { i8, %str_slice, [48 x i8] }, { i8, { { i8, [15 x i8] }, { i32, i8, i64, { i8, [15 x i8] }, { i8, [15 x i8] } } }, [0 x i8] }, { i8, %str_slice, [48 x i8] }, { i8, { { i8, [15 x i8] }, { i32, i8, i64, { i8, [15 x i8] }, { i8, [15 x i8] } } }, [0 x i8] }, { i8, %str_slice, [48 x i8] } }* @"_ZN3str39_$BP$$x27a$x20str.StrSlice$LT$$x27a$GT$5slice15__STATIC_FMTSTR20hecbbb0a2a6789145mDrE" to %"enum.core::fmt::rt::Piece<[]>[#3]"*), %"enum.core::fmt::rt::Piece<[]>[#3]"** %__adjust.sroa.0.0..sroa_idx.i, align 8
  %__adjust.sroa.4.0..sroa_idx34.i = getelementptr inbounds %"struct.core::fmt::Arguments<[]>[#3]"* %__args.i, i64 0, i32 0, i32 1
  store i64 7, i64* %__adjust.sroa.4.0..sroa_idx34.i, align 8
  %__adjust.sroa.0.0..sroa_idx.i27.i = getelementptr inbounds %"struct.core::fmt::Arguments<[]>[#3]"* %__args.i, i64 0, i32 1, i32 0
  store %"struct.core::fmt::Argument<[]>[#3]"* %.sub.i, %"struct.core::fmt::Argument<[]>[#3]"** %__adjust.sroa.0.0..sroa_idx.i27.i, align 8
  %__adjust.sroa.3.0..sroa_idx1.i.i = getelementptr inbounds %"struct.core::fmt::Arguments<[]>[#3]"* %__args.i, i64 0, i32 1, i32 1
  store i64 3, i64* %__adjust.sroa.3.0..sroa_idx1.i.i, align 8
  call void @_ZN7failure12begin_unwind20hd0af3f4657afff41yAkE(%"struct.core::fmt::Arguments<[]>[#3]"* noalias nocapture readonly dereferenceable(32) %__args.i, { %str_slice, i64 }* noalias nocapture readonly dereferenceable(24) @"_ZN3str39_$BP$$x27a$x20str.StrSlice$LT$$x27a$GT$5slice8_run_fmt10_FILE_LINE20h4965d27d95ea2255QCrE")
  unreachable

next-block.i:                                     ; preds = %before_rhs.next-block_crit_edge.i, %join.i
  %arg.sroa.0.0.copyload.i = phi i8* [ %arg.sroa.0.0.copyload.pre.i, %before_rhs.next-block_crit_edge.i ], [ %.sroa.0.0.copyload.i17.i, %join.i ]
  %33 = icmp ult i64 %3, %2
  br i1 %33, label %then-block-583-.i.i, label %next-block.i24.i

then-block-583-.i.i:                              ; preds = %next-block.i
  %34 = bitcast %str_slice* %4 to i8*
  call void @llvm.lifetime.start(i64 16, i8* %34)
  %35 = getelementptr inbounds %str_slice* %4, i64 0, i32 0
  store i8* getelementptr inbounds ([30 x i8]* @str1159, i64 0, i64 0), i8** %35, align 8
  %36 = getelementptr inbounds %str_slice* %4, i64 0, i32 1
  store i64 30, i64* %36, align 8
  %37 = bitcast %"struct.core::fmt::Argument<[]>[#3]"* %5 to i8*
  call void @llvm.lifetime.start(i64 16, i8* %37)
  %38 = getelementptr inbounds %"struct.core::fmt::Argument<[]>[#3]"* %5, i64 0, i32 0
  store %"enum.core::result::Result<[(), core::fmt::FormatError]>[#3]" (%"enum.core::fmt::Void<[]>[#3]"*, %"struct.core::fmt::Formatter<[]>[#3]"*)* bitcast (%"enum.core::result::Result<[(), core::fmt::FormatError]>[#3]" (%str_slice*, %"struct.core::fmt::Formatter<[]>[#3]"*)* @_ZN3fmt11secret_show20h8865777717318847987E to %"enum.core::result::Result<[(), core::fmt::FormatError]>[#3]" (%"enum.core::fmt::Void<[]>[#3]"*, %"struct.core::fmt::Formatter<[]>[#3]"*)*), %"enum.core::result::Result<[(), core::fmt::FormatError]>[#3]" (%"enum.core::fmt::Void<[]>[#3]"*, %"struct.core::fmt::Formatter<[]>[#3]"*)** %38, align 8
  %39 = getelementptr inbounds %"struct.core::fmt::Argument<[]>[#3]"* %5, i64 0, i32 1
  %.c.i.i.i = bitcast %str_slice* %4 to %"enum.core::fmt::Void<[]>[#3]"*
  store %"enum.core::fmt::Void<[]>[#3]"* %.c.i.i.i, %"enum.core::fmt::Void<[]>[#3]"** %39, align 8
  %40 = bitcast %"struct.core::fmt::Arguments<[]>[#3]"* %__args.i.i to i8*
  call void @llvm.lifetime.start(i64 32, i8* %40)
  %__adjust.sroa.0.0..sroa_idx.i.i = getelementptr inbounds %"struct.core::fmt::Arguments<[]>[#3]"* %__args.i.i, i64 0, i32 0, i32 0
  store %"enum.core::fmt::rt::Piece<[]>[#3]"* bitcast ({ { i8, { { i8, [15 x i8] }, { i32, i8, i64, { i8, [15 x i8] }, { i8, [15 x i8] } } }, [0 x i8] } }* @_ZN3str3raw11slice_bytes15__STATIC_FMTSTR20hf82a49d95a7811fb4irE to %"enum.core::fmt::rt::Piece<[]>[#3]"*), %"enum.core::fmt::rt::Piece<[]>[#3]"** %__adjust.sroa.0.0..sroa_idx.i.i, align 8
  %__adjust.sroa.4.0..sroa_idx37.i.i = getelementptr inbounds %"struct.core::fmt::Arguments<[]>[#3]"* %__args.i.i, i64 0, i32 0, i32 1
  store i64 1, i64* %__adjust.sroa.4.0..sroa_idx37.i.i, align 8
  %__adjust.sroa.0.0..sroa_idx.i.i.i = getelementptr inbounds %"struct.core::fmt::Arguments<[]>[#3]"* %__args.i.i, i64 0, i32 1, i32 0
  store %"struct.core::fmt::Argument<[]>[#3]"* %5, %"struct.core::fmt::Argument<[]>[#3]"** %__adjust.sroa.0.0..sroa_idx.i.i.i, align 8
  %__adjust.sroa.3.0..sroa_idx1.i.i.i = getelementptr inbounds %"struct.core::fmt::Arguments<[]>[#3]"* %__args.i.i, i64 0, i32 1, i32 1
  store i64 1, i64* %__adjust.sroa.3.0..sroa_idx1.i.i.i, align 8
  call void @_ZN7failure12begin_unwind20hd0af3f4657afff41yAkE(%"struct.core::fmt::Arguments<[]>[#3]"* noalias nocapture readonly dereferenceable(32) %__args.i.i, { %str_slice, i64 }* noalias nocapture readonly dereferenceable(24) @_ZN3str3raw11slice_bytes8_run_fmt10_FILE_LINE20h4965d27d95ea2255ghrE)
  unreachable

next-block.i24.i:                                 ; preds = %next-block.i
  %41 = icmp ult i64 %.sroa.3.0.copyload.i.i.i, %3
  br i1 %41, label %then-block-670-.i.i, label %"_ZN3str39_$BP$$x27a$x20str.StrSlice$LT$$x27a$GT$5slice20he30e5671c97c5789AaaE.exit"

then-block-670-.i.i:                              ; preds = %next-block.i24.i
  %42 = bitcast %str_slice* %6 to i8*
  call void @llvm.lifetime.start(i64 16, i8* %42)
  %43 = getelementptr inbounds %str_slice* %6, i64 0, i32 0
  store i8* getelementptr inbounds ([32 x i8]* @str1160, i64 0, i64 0), i8** %43, align 8
  %44 = getelementptr inbounds %str_slice* %6, i64 0, i32 1
  store i64 32, i64* %44, align 8
  %45 = bitcast %"struct.core::fmt::Argument<[]>[#3]"* %7 to i8*
  call void @llvm.lifetime.start(i64 16, i8* %45)
  %46 = getelementptr inbounds %"struct.core::fmt::Argument<[]>[#3]"* %7, i64 0, i32 0
  store %"enum.core::result::Result<[(), core::fmt::FormatError]>[#3]" (%"enum.core::fmt::Void<[]>[#3]"*, %"struct.core::fmt::Formatter<[]>[#3]"*)* bitcast (%"enum.core::result::Result<[(), core::fmt::FormatError]>[#3]" (%str_slice*, %"struct.core::fmt::Formatter<[]>[#3]"*)* @_ZN3fmt11secret_show20h8865777717318847987E to %"enum.core::result::Result<[(), core::fmt::FormatError]>[#3]" (%"enum.core::fmt::Void<[]>[#3]"*, %"struct.core::fmt::Formatter<[]>[#3]"*)*), %"enum.core::result::Result<[(), core::fmt::FormatError]>[#3]" (%"enum.core::fmt::Void<[]>[#3]"*, %"struct.core::fmt::Formatter<[]>[#3]"*)** %46, align 8
  %47 = getelementptr inbounds %"struct.core::fmt::Argument<[]>[#3]"* %7, i64 0, i32 1
  %.c.i25.i.i = bitcast %str_slice* %6 to %"enum.core::fmt::Void<[]>[#3]"*
  store %"enum.core::fmt::Void<[]>[#3]"* %.c.i25.i.i, %"enum.core::fmt::Void<[]>[#3]"** %47, align 8
  %48 = bitcast %"struct.core::fmt::Arguments<[]>[#3]"* %__args7.i.i to i8*
  call void @llvm.lifetime.start(i64 32, i8* %48)
  %__adjust8.sroa.0.0..sroa_idx.i.i = getelementptr inbounds %"struct.core::fmt::Arguments<[]>[#3]"* %__args7.i.i, i64 0, i32 0, i32 0
  store %"enum.core::fmt::rt::Piece<[]>[#3]"* bitcast ({ { i8, { { i8, [15 x i8] }, { i32, i8, i64, { i8, [15 x i8] }, { i8, [15 x i8] } } }, [0 x i8] } }* @_ZN3str3raw11slice_bytes15__STATIC_FMTSTR20hf82a49d95a7811fb4irE to %"enum.core::fmt::rt::Piece<[]>[#3]"*), %"enum.core::fmt::rt::Piece<[]>[#3]"** %__adjust8.sroa.0.0..sroa_idx.i.i, align 8
  %__adjust8.sroa.4.0..sroa_idx32.i.i = getelementptr inbounds %"struct.core::fmt::Arguments<[]>[#3]"* %__args7.i.i, i64 0, i32 0, i32 1
  store i64 1, i64* %__adjust8.sroa.4.0..sroa_idx32.i.i, align 8
  %__adjust.sroa.0.0..sroa_idx.i23.i.i = getelementptr inbounds %"struct.core::fmt::Arguments<[]>[#3]"* %__args7.i.i, i64 0, i32 1, i32 0
  store %"struct.core::fmt::Argument<[]>[#3]"* %7, %"struct.core::fmt::Argument<[]>[#3]"** %__adjust.sroa.0.0..sroa_idx.i23.i.i, align 8
  %__adjust.sroa.3.0..sroa_idx1.i24.i.i = getelementptr inbounds %"struct.core::fmt::Arguments<[]>[#3]"* %__args7.i.i, i64 0, i32 1, i32 1
  store i64 1, i64* %__adjust.sroa.3.0..sroa_idx1.i24.i.i, align 8
  call void @_ZN7failure12begin_unwind20hd0af3f4657afff41yAkE(%"struct.core::fmt::Arguments<[]>[#3]"* noalias nocapture readonly dereferenceable(32) %__args7.i.i, { %str_slice, i64 }* noalias nocapture readonly dereferenceable(24) @_ZN3str3raw11slice_bytes8_run_fmt10_FILE_LINE20h4965d27d95ea2255FirE)
  unreachable

"_ZN3str39_$BP$$x27a$x20str.StrSlice$LT$$x27a$GT$5slice20he30e5671c97c5789AaaE.exit": ; preds = %next-block.i24.i
  %49 = getelementptr inbounds %str_slice* %0, i64 0, i32 0
  %50 = getelementptr inbounds i8* %arg.sroa.0.0.copyload.i, i64 %2
  store i8* %50, i8** %49, align 8
  %51 = getelementptr inbounds %str_slice* %0, i64 0, i32 1
  %52 = sub i64 %3, %2
  store i64 %52, i64* %51, align 8
  call void @llvm.lifetime.end(i64 8, i8* %10)
  call void @llvm.lifetime.end(i64 8, i8* %9)
  %53 = bitcast %str_slice* %1 to i8*
  tail call void @llvm.lifetime.end(i64 16, i8* %53)
  ret void
}

The worst part is there's five separate sites that unwind (each unreachable is just after an unwinding function) due to various assertions and bounds-checks. (&[].slice is mildly better.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    I-slowIssue: Problems and improvements with respect to performance of generated code.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions