diff --git a/llvm/lib/CodeGen/CalcSpillWeights.cpp b/llvm/lib/CodeGen/CalcSpillWeights.cpp --- a/llvm/lib/CodeGen/CalcSpillWeights.cpp +++ b/llvm/lib/CodeGen/CalcSpillWeights.cpp @@ -209,6 +209,11 @@ I != E;) { MachineInstr *mi = &*(I++); + if (mi->getOpcode() == TargetOpcode::INLINEASM_BR) { + li.markNotSpillable(); + return -1.0; + } + // For local split artifacts, we are interested only in instructions between // the expected start and end of the range. SlotIndex si = LIS.getInstructionIndex(*mi); diff --git a/llvm/test/CodeGen/X86/callbr-asm-regalloc.mir b/llvm/test/CodeGen/X86/callbr-asm-regalloc.mir new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/X86/callbr-asm-regalloc.mir @@ -0,0 +1,312 @@ +# RUN: llc -run-pass=greedy -regalloc=greedy -verify-regalloc %s +# Dumped via: +# $ llc -stop-after=machine-scheduler -simplify-mir \ +# -o callbr-asm-regalloc.mir llvm/test/CodeGen/X86/callbr-asm-regalloc.ll +--- | + ; ModuleID = 'callbr-asm-regalloc.ll' + source_filename = "callbr-asm-regalloc.ll" + target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + + %struct.d = type { i8* } + %struct.b = type {} + + @j = dso_local local_unnamed_addr global i32 0, align 4 + @i = dso_local local_unnamed_addr global i32 0, align 4 + @h = dso_local local_unnamed_addr global i32 0, align 4 + @g = dso_local local_unnamed_addr global i32 0, align 4 + + define dso_local i32 @cmsghdr_from_user_compat_to_kern(%struct.d* %0) { + %const = bitcast i64 8589934590 to i64 + br label %2 + + 2: ; preds = %11, %1 + %3 = phi i32 [ %16, %11 ], [ undef, %1 ] + %4 = load i32, i32* @j, align 4 + %5 = zext i32 %4 to i64 + %6 = load i32, i32* @i, align 4 + %7 = icmp eq i32 %6, 0 + br i1 %7, label %8, label %46 + + 8: ; preds = %2 + %9 = trunc i64 %5 to i32 + %10 = icmp eq i32 %9, 0 + br i1 %10, label %46, label %11 + + 11: ; preds = %8 + %12 = trunc i64 %5 to i32 + %13 = add nuw nsw i64 %5, 1 + %14 = and i64 %13, %const + %15 = trunc i64 %14 to i32 + store i32 %15, i32* @h, align 4 + %16 = tail call i32 @f(%struct.d* %0, i32 %3, i32 %12) + %17 = icmp eq i32 %16, 0 + br i1 %17, label %18, label %2 + + 18: ; preds = %11 + %19 = icmp eq i64 %14, 0 + br i1 %19, label %20, label %46 + + 20: ; preds = %18 + %21 = icmp eq %struct.d* %0, null + br i1 %21, label %46, label %22 + + 22: ; preds = %20 + %23 = bitcast %struct.d* %0 to i64* + %24 = load i64, i64* %23, align 8 + %25 = trunc i64 %24 to i32 + %26 = icmp eq i32 %25, 0 + br i1 %26, label %46, label %.preheader, !prof !0 + + .preheader: ; preds = %22 + br label %27 + + 27: ; preds = %.preheader, %40 + %28 = phi i32 [ %44, %40 ], [ %25, %.preheader ] + %29 = phi i64 [ %43, %40 ], [ 0, %.preheader ] + %30 = callbr i32 asm "1:\09mov $1,$0\0A .pushsection \22__ex_table\22,\22a\22\0A .long 1b - .\0A .long ${2:l} - .\0A .long 0 - .\0A .popsection\0A", "=r,*m,X,~{dirflag},~{fpsr},~{flags}"(%struct.b* null, i8* blockaddress(@cmsghdr_from_user_compat_to_kern, %31)) + to label %33 [label %31] + + 31: ; preds = %27 + %32 = tail call i32 @a() + br label %46 + + 33: ; preds = %27 + %34 = zext i32 %30 to i64 + %35 = shl i64 %29, 32 + %36 = ashr exact i64 %35, 32 + %37 = inttoptr i64 %36 to i32* + %38 = tail call i32 @c(i32* %37, i64 %34) + %39 = icmp eq i32 %38, 0 + br i1 %39, label %40, label %46 + + 40: ; preds = %33 + %41 = add nuw nsw i64 %34, 8 + %42 = and i64 %41, %const + %43 = add nsw i64 %42, %36 + %44 = tail call i32 @f(%struct.d* nonnull %0, i32 %28, i32 %30) + %45 = icmp eq i32 %44, 0 + br i1 %45, label %46, label %27, !prof !0 + + 46: ; preds = %8, %2, %40, %33, %31, %22, %20, %18 + %47 = phi i32 [ -22, %18 ], [ undef, %31 ], [ undef, %22 ], [ undef, %20 ], [ undef, %33 ], [ undef, %40 ], [ 4, %2 ], [ -22, %8 ] + ret i32 %47 + } + + declare dso_local i32 @f(%struct.d*, i32, i32) local_unnamed_addr + + declare dso_local i32 @a() local_unnamed_addr + + declare dso_local i32 @c(i32*, i64) local_unnamed_addr + + define dso_local i32 @put_cmsg_compat() local_unnamed_addr { + ret i32 undef + } + + ; Function Attrs: nounwind + declare void @llvm.stackprotector(i8*, i8**) #0 + + attributes #0 = { nounwind } + + !0 = !{!"branch_weights", i32 2146410443, i32 1073205} + +... +--- +name: cmsghdr_from_user_compat_to_kern +alignment: 16 +tracksRegLiveness: true +registers: + - { id: 0, class: gr64 } + - { id: 1, class: gr32 } + - { id: 2, class: gr64_with_sub_8bit } + - { id: 3, class: gr64_with_sub_8bit } + - { id: 4, class: gr32 } + - { id: 5, class: gr32 } + - { id: 6, class: gr32 } + - { id: 7, class: gr64 } + - { id: 8, class: gr32 } + - { id: 9, class: gr64_with_sub_8bit } + - { id: 10, class: gr64 } + - { id: 11, class: gr64 } + - { id: 12, class: gr32 } + - { id: 13, class: gr32 } + - { id: 14, class: gr64 } + - { id: 15, class: gr32 } + - { id: 16, class: gr32 } + - { id: 17, class: gr32 } + - { id: 18, class: gr32 } + - { id: 19, class: gr32 } + - { id: 20, class: gr32 } + - { id: 21, class: gr64 } + - { id: 22, class: gr32 } + - { id: 23, class: gr32 } + - { id: 24, class: gr32 } + - { id: 25, class: gr32 } + - { id: 26, class: gr32 } + - { id: 27, class: gr64_with_sub_8bit } + - { id: 28, class: gr32 } + - { id: 29, class: gr32 } + - { id: 30, class: gr32 } + - { id: 31, class: gr32 } + - { id: 32, class: gr32 } + - { id: 33, class: gr32 } + - { id: 34, class: gr32 } + - { id: 35, class: gr32 } + - { id: 36, class: gr32 } + - { id: 37, class: gr64_with_sub_8bit } + - { id: 38, class: gr64_with_sub_8bit } + - { id: 39, class: gr32 } + - { id: 40, class: gr32 } + - { id: 41, class: gr32 } + - { id: 42, class: gr64_with_sub_8bit } + - { id: 43, class: gr32 } +liveins: + - { reg: '$rdi', virtual-reg: '%14' } +frameInfo: + maxAlignment: 1 + hasCalls: true +machineFunctionInfo: {} +body: | + bb.0 (%ir-block.1): + liveins: $rdi + + %14:gr64 = COPY $rdi + %0:gr64 = MOV64ri 8589934590 + %1:gr32 = IMPLICIT_DEF + + bb.1 (%ir-block.2): + successors: %bb.3(0x7c000000), %bb.2(0x04000000) + + CMP32mi8 $rip, 1, $noreg, @i, $noreg, 0, implicit-def $eflags :: (dereferenceable load 4 from @i) + JCC_1 %bb.3, 4, implicit killed $eflags + + bb.2: + %43:gr32 = MOV32ri 4 + JMP_1 %bb.15 + + bb.3 (%ir-block.8): + successors: %bb.16(0x04000000), %bb.4(0x7c000000) + + undef %2.sub_32bit:gr64_with_sub_8bit = MOV32rm $rip, 1, $noreg, @j, $noreg :: (dereferenceable load 4 from @j) + %43:gr32 = MOV32ri -22 + TEST32rr %2.sub_32bit, %2.sub_32bit, implicit-def $eflags + JCC_1 %bb.4, 5, implicit killed $eflags + + bb.16: + JMP_1 %bb.15 + + bb.4 (%ir-block.11): + successors: %bb.5(0x04000000), %bb.1(0x7c000000) + + %3:gr64_with_sub_8bit = COPY %2 + %3:gr64_with_sub_8bit = nuw nsw INC64r %3, implicit-def dead $eflags + %3:gr64_with_sub_8bit = AND64rr %3, %0, implicit-def dead $eflags + MOV32mr $rip, 1, $noreg, @h, $noreg, %3.sub_32bit :: (store 4 into @h) + ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp + $rdi = COPY %14 + $esi = COPY %1 + $edx = COPY %2.sub_32bit + CALL64pcrel32 @f, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit killed $esi, implicit killed $edx, implicit-def $rsp, implicit-def $ssp, implicit-def $eax + ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp + %1:gr32 = COPY killed $eax + TEST32rr %1, %1, implicit-def $eflags + JCC_1 %bb.1, 5, implicit killed $eflags + JMP_1 %bb.5 + + bb.5 (%ir-block.18): + successors: %bb.6(0x30000000), %bb.15(0x50000000) + + TEST64rr %3, %3, implicit-def $eflags + JCC_1 %bb.15, 5, implicit killed $eflags + JMP_1 %bb.6 + + bb.6 (%ir-block.20): + successors: %bb.7(0x30000000), %bb.8(0x50000000) + + TEST64rr %14, %14, implicit-def $eflags + JCC_1 %bb.8, 5, implicit killed $eflags + + bb.7: + %43:gr32 = IMPLICIT_DEF + JMP_1 %bb.15 + + bb.8 (%ir-block.22): + successors: %bb.15(0x7fef9fcb), %bb.9(0x00106035) + + %41:gr32 = MOV32rm %14, 1, $noreg, 0, $noreg :: (load 4 from %ir.23, align 8) + TEST32rr %41, %41, implicit-def $eflags + %43:gr32 = IMPLICIT_DEF + JCC_1 %bb.15, 4, implicit killed $eflags + JMP_1 %bb.9 + + bb.9..preheader: + undef %42.sub_32bit:gr64_with_sub_8bit = MOV32r0 implicit-def dead $eflags + + bb.10 (%ir-block.27): + successors: %bb.12(0x00000000), %bb.11(0x80000000) + + INLINEASM_BR &"1:\09mov $1,$0\0A .pushsection \22__ex_table\22,\22a\22\0A .long 1b - .\0A .long ${2:l} - .\0A .long 0 - .\0A .popsection\0A", 8, 2228234, def %8, 196654, $noreg, 1, $noreg, 0, $noreg, 13, blockaddress(@cmsghdr_from_user_compat_to_kern, %ir-block.31), 12, implicit-def dead early-clobber $df, 12, implicit-def early-clobber $fpsw, 12, implicit-def dead early-clobber $eflags + + bb.11 (%ir-block.27): + JMP_1 %bb.13 + + bb.12 (%ir-block.31, address-taken): + ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp + CALL64pcrel32 @a, csr_64, implicit $rsp, implicit $ssp, implicit-def $rsp, implicit-def $ssp, implicit-def dead $eax + ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp + %43:gr32 = IMPLICIT_DEF + JMP_1 %bb.15 + + bb.13 (%ir-block.33): + successors: %bb.14(0x7c000000), %bb.15(0x04000000) + + undef %38.sub_32bit:gr64_with_sub_8bit = MOV32rr %8 + %10:gr64 = MOVSX64rr32 %42.sub_32bit + ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp + $rdi = COPY %10 + $rsi = COPY %38 + CALL64pcrel32 @c, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit killed $rsi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax + ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp + %35:gr32 = COPY killed $eax + TEST32rr %35, %35, implicit-def $eflags + %43:gr32 = IMPLICIT_DEF + JCC_1 %bb.15, 5, implicit killed $eflags + JMP_1 %bb.14 + + bb.14 (%ir-block.40): + successors: %bb.15(0x7fef9fcb), %bb.10(0x00106035) + + %38:gr64_with_sub_8bit = nuw nsw ADD64ri8 %38, 8, implicit-def dead $eflags + %38:gr64_with_sub_8bit = AND64rr %38, %0, implicit-def dead $eflags + %38:gr64_with_sub_8bit = nsw ADD64rr %38, %10, implicit-def dead $eflags + ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp + $rdi = COPY %14 + $esi = COPY %41 + $edx = COPY %8 + CALL64pcrel32 @f, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit killed $esi, implicit killed $edx, implicit-def $rsp, implicit-def $ssp, implicit-def $eax + ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp + %41:gr32 = COPY killed $eax + TEST32rr %41, %41, implicit-def $eflags + %42:gr64_with_sub_8bit = COPY %38 + %43:gr32 = IMPLICIT_DEF + JCC_1 %bb.10, 5, implicit killed $eflags + JMP_1 %bb.15 + + bb.15 (%ir-block.46): + $eax = COPY %43 + RET 0, killed $eax + +... +--- +name: put_cmsg_compat +alignment: 16 +tracksRegLiveness: true +registers: + - { id: 0, class: gr32 } +frameInfo: + maxAlignment: 1 +machineFunctionInfo: {} +body: | + bb.0 (%ir-block.0): + RET 0, undef $eax + +...