Author: matze Date: Thu Feb 9 15:45:33 2017 New Revision: 294631 URL: http://llvm.org/viewvc/llvm-project?rev=294631&view=rev Log: RegisterCoalescer: Fix joinReservedPhysReg()
Merging r294268: joinReservedPhysReg() can only deal with a liverange in a single basic block when copying from a vreg into a physreg. See also rdar://30306405 Differential Revision: https://reviews.llvm.org/D29436 Fixes http://llvm.org/PR31889 Modified: llvm/branches/release_40/lib/CodeGen/RegisterCoalescer.cpp llvm/branches/release_40/test/CodeGen/AArch64/regcoal-physreg.mir Modified: llvm/branches/release_40/lib/CodeGen/RegisterCoalescer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/branches/release_40/lib/CodeGen/RegisterCoalescer.cpp?rev=294631&r1=294630&r2=294631&view=diff ============================================================================== --- llvm/branches/release_40/lib/CodeGen/RegisterCoalescer.cpp (original) +++ llvm/branches/release_40/lib/CodeGen/RegisterCoalescer.cpp Thu Feb 9 15:45:33 2017 @@ -1614,6 +1614,11 @@ bool RegisterCoalescer::joinReservedPhys return false; } + if (!LIS->intervalIsInOneMBB(RHS)) { + DEBUG(dbgs() << "\t\tComplex control flow!\n"); + return false; + } + MachineInstr &DestMI = *MRI->getVRegDef(SrcReg); CopyMI = &*MRI->use_instr_nodbg_begin(SrcReg); SlotIndex CopyRegIdx = LIS->getInstructionIndex(*CopyMI).getRegSlot(); Modified: llvm/branches/release_40/test/CodeGen/AArch64/regcoal-physreg.mir URL: http://llvm.org/viewvc/llvm-project/llvm/branches/release_40/test/CodeGen/AArch64/regcoal-physreg.mir?rev=294631&r1=294630&r2=294631&view=diff ============================================================================== --- llvm/branches/release_40/test/CodeGen/AArch64/regcoal-physreg.mir (original) +++ llvm/branches/release_40/test/CodeGen/AArch64/regcoal-physreg.mir Thu Feb 9 15:45:33 2017 @@ -1,19 +1,24 @@ # RUN: llc -mtriple=aarch64-apple-ios -run-pass=simple-register-coalescing %s -o - | FileCheck %s --- | - define void @func() { ret void } + define void @func0() { ret void } + define void @func1() { ret void } + define void @func2() { ret void } ... --- # Check coalescing of COPYs from reserved physregs. -# CHECK-LABEL: name: func -name: func +# CHECK-LABEL: name: func0 +name: func0 registers: - - { id: 0, class: gpr32 } - - { id: 1, class: gpr64 } - - { id: 2, class: gpr64 } - - { id: 3, class: gpr32 } - - { id: 4, class: gpr64 } - - { id: 5, class: gpr32 } - - { id: 6, class: xseqpairsclass } + - { id: 0, class: gpr32 } + - { id: 1, class: gpr64 } + - { id: 2, class: gpr64 } + - { id: 3, class: gpr32 } + - { id: 4, class: gpr64 } + - { id: 5, class: gpr32 } + - { id: 6, class: xseqpairsclass } + - { id: 7, class: gpr64 } + - { id: 8, class: gpr64sp } + - { id: 9, class: gpr64sp } body: | bb.0: ; We usually should not coalesce copies from allocatable physregs. @@ -60,8 +65,74 @@ body: | ; Only coalesce when the source register is reserved as a whole (this is ; a limitation of the current code which cannot update liveness information ; of the non-reserved part). - ; CHECK: %6 = COPY %xzr_x0 + ; CHECK: %6 = COPY %x28_fp ; CHECK: HINT 0, implicit %6 - %6 = COPY %xzr_x0 + %6 = COPY %x28_fp HINT 0, implicit %6 + + ; This can be coalesced. + ; CHECK: %fp = SUBXri %fp, 4, 0 + %8 = SUBXri %fp, 4, 0 + %fp = COPY %8 + + ; Cannot coalesce when there are reads of the physreg. + ; CHECK-NOT: %fp = SUBXri %fp, 8, 0 + ; CHECK: %9 = SUBXri %fp, 8, 0 + ; CHECK: STRXui %fp, %fp, 0 + ; CHECK: %fp = COPY %9 + %9 = SUBXri %fp, 8, 0 + STRXui %fp, %fp, 0 + %fp = COPY %9 +... +--- +# Check coalescing of COPYs from reserved physregs. +# CHECK-LABEL: name: func1 +name: func1 +registers: + - { id: 0, class: gpr64sp } +body: | + bb.0: + successors: %bb.1, %bb.2 + ; Cannot coalesce physreg because we have reads on other CFG paths (we + ; currently abort for any control flow) + ; CHECK-NOT: %fp = SUBXri + ; CHECK: %0 = SUBXri %fp, 12, 0 + ; CHECK: CBZX undef %x0, %bb.1 + ; CHECK: B %bb.2 + %0 = SUBXri %fp, 12, 0 + CBZX undef %x0, %bb.1 + B %bb.2 + + bb.1: + %fp = COPY %0 + RET_ReallyLR + + bb.2: + STRXui %fp, %fp, 0 + RET_ReallyLR +... +--- +# CHECK-LABEL: name: func2 +name: func2 +registers: + - { id: 0, class: gpr64sp } +body: | + bb.0: + successors: %bb.1, %bb.2 + ; We can coalesce copies from physreg to vreg across multiple blocks. + ; CHECK-NOT: COPY + ; CHECK: CBZX undef %x0, %bb.1 + ; CHECK-NEXT: B %bb.2 + %0 = COPY %fp + CBZX undef %x0, %bb.1 + B %bb.2 + + bb.1: + ; CHECK: STRXui undef %x0, %fp, 0 + ; CHECK-NEXT: RET_ReallyLR + STRXui undef %x0, %0, 0 + RET_ReallyLR + + bb.2: + RET_ReallyLR ... _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits