diff --git a/llvm/include/llvm/CodeGen/LiveVariables.h b/llvm/include/llvm/CodeGen/LiveVariables.h index d75cddfdfb07a..ef1aeede873aa 100644 --- a/llvm/include/llvm/CodeGen/LiveVariables.h +++ b/llvm/include/llvm/CodeGen/LiveVariables.h @@ -164,10 +164,8 @@ class LiveVariables { MachineInstr *FindLastRefOrPartRef(Register Reg); /// FindLastPartialDef - Return the last partial def of the specified - /// register. Also returns the sub-registers that're defined by the - /// instruction. - MachineInstr *FindLastPartialDef(Register Reg, - SmallSet &PartDefRegs); + /// register. + MachineInstr *FindLastPartialDef(Register Reg); /// analyzePHINodes - Gather information about the PHI nodes in here. In /// particular, we want to map the variable information of a virtual diff --git a/llvm/lib/CodeGen/LiveVariables.cpp b/llvm/lib/CodeGen/LiveVariables.cpp index f0bb439e82372..b39603ea40166 100644 --- a/llvm/lib/CodeGen/LiveVariables.cpp +++ b/llvm/lib/CodeGen/LiveVariables.cpp @@ -214,11 +214,7 @@ void LiveVariables::HandleVirtRegDef(Register Reg, MachineInstr &MI) { } /// FindLastPartialDef - Return the last partial def of the specified register. -/// Also returns the sub-registers that're defined by the instruction. -MachineInstr * -LiveVariables::FindLastPartialDef(Register Reg, - SmallSet &PartDefRegs) { - Register LastDefReg = 0; +MachineInstr *LiveVariables::FindLastPartialDef(Register Reg) { unsigned LastDefDist = 0; MachineInstr *LastDef = nullptr; for (MCPhysReg SubReg : TRI->subregs(Reg)) { @@ -227,7 +223,6 @@ LiveVariables::FindLastPartialDef(Register Reg, continue; unsigned Dist = DistanceMap[Def]; if (Dist > LastDefDist) { - LastDefReg = SubReg; LastDef = Def; LastDefDist = Dist; } @@ -236,14 +231,6 @@ LiveVariables::FindLastPartialDef(Register Reg, if (!LastDef) return nullptr; - PartDefRegs.insert(LastDefReg); - for (MachineOperand &MO : LastDef->all_defs()) { - if (MO.getReg() == 0) - continue; - Register DefReg = MO.getReg(); - if (TRI->isSubRegister(Reg, DefReg)) - PartDefRegs.insert_range(TRI->subregs_inclusive(DefReg)); - } return LastDef; } @@ -262,27 +249,11 @@ void LiveVariables::HandlePhysRegUse(Register Reg, MachineInstr &MI) { // ... // = EAX // All of the sub-registers must have been defined before the use of Reg! - SmallSet PartDefRegs; - MachineInstr *LastPartialDef = FindLastPartialDef(Reg, PartDefRegs); + MachineInstr *LastPartialDef = FindLastPartialDef(Reg); // If LastPartialDef is NULL, it must be using a livein register. if (LastPartialDef) { - LastPartialDef->addOperand(MachineOperand::CreateReg(Reg, true/*IsDef*/, - true/*IsImp*/)); - PhysRegDef[Reg.id()] = LastPartialDef; - SmallSet Processed; - for (MCPhysReg SubReg : TRI->subregs(Reg)) { - if (Processed.count(SubReg)) - continue; - if (PartDefRegs.count(SubReg)) - continue; - // This part of Reg was defined before the last partial def. It's killed - // here. - LastPartialDef->addOperand(MachineOperand::CreateReg(SubReg, - false/*IsDef*/, - true/*IsImp*/)); - PhysRegDef[SubReg] = LastPartialDef; - Processed.insert_range(TRI->subregs(SubReg)); - } + LastPartialDef->addOperand( + MachineOperand::CreateReg(Reg, /*IsDef=*/true, /*IsImp=*/true)); } } else if (LastDef && !PhysRegUse[Reg.id()] && !LastDef->findRegisterDefOperand(Reg, /*TRI=*/nullptr)) diff --git a/llvm/test/CodeGen/AArch64/ldrpre-ldr-merge.mir b/llvm/test/CodeGen/AArch64/ldrpre-ldr-merge.mir index a10d7588cb442..8a5e0f6aa843a 100644 --- a/llvm/test/CodeGen/AArch64/ldrpre-ldr-merge.mir +++ b/llvm/test/CodeGen/AArch64/ldrpre-ldr-merge.mir @@ -756,7 +756,7 @@ body: | ; CHECK: liveins: $x0, $x1, $x2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: early-clobber renamable $x1, renamable $x0 = LDRSWpre renamable $x1, 40, implicit $w1, implicit $w1_hi :: (load (s32)) - ; CHECK-NEXT: renamable $w2 = LDRWui renamable $x1, 1, implicit-def $x2, implicit $w2_hi :: (load (s32)) + ; CHECK-NEXT: renamable $w2 = LDRWui renamable $x1, 1, implicit-def $x2 :: (load (s32)) ; CHECK-NEXT: STPXi renamable $x0, renamable $x2, renamable $x1, 0 :: (store (s64)) ; CHECK-NEXT: RET undef $lr early-clobber renamable $x1, renamable $x0 = LDRSWpre killed renamable $x1, 40 :: (load (s32)) diff --git a/llvm/test/CodeGen/AMDGPU/fncall-implicitdef.ll b/llvm/test/CodeGen/AMDGPU/fncall-implicitdef.ll new file mode 100644 index 0000000000000..66a8b424b5763 --- /dev/null +++ b/llvm/test/CodeGen/AMDGPU/fncall-implicitdef.ll @@ -0,0 +1,25 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 +; RUN: llc -mtriple=amdgcn-amd-amdpal -mcpu=gfx900 -O1 %s -o - | FileCheck %s + +define amdgpu_ps <4 x float> @caller(ptr %ptr) { +; CHECK-LABEL: caller: +; CHECK: ; %bb.0: +; CHECK-NEXT: flat_load_dword v1, v[0:1] +; CHECK-NEXT: s_mov_b32 s0, 0 +; CHECK-NEXT: s_mov_b32 s1, 0 +; CHECK-NEXT: s_mov_b32 s2, 0 +; CHECK-NEXT: s_mov_b32 s5, fn@abs32@hi +; CHECK-NEXT: s_mov_b32 s4, fn@abs32@lo +; CHECK-NEXT: s_mov_b64 s[8:9], 0 +; CHECK-NEXT: v_mov_b32_e32 v0, 0 +; CHECK-NEXT: s_mov_b32 s3, 0 +; CHECK-NEXT: v_mov_b32_e32 v2, 0 +; CHECK-NEXT: s_mov_b32 s32, 0 +; CHECK-NEXT: s_swappc_b64 s[30:31], s[4:5] +; CHECK-NEXT: ; return to shader part epilog + %L = load i32, ptr %ptr, align 4 + %R = call <4 x float> @fn(<4 x i32> zeroinitializer, i32 0, i32 %L, i32 0) + ret <4 x float> %R +} + +declare hidden <4 x float> @fn(<4 x i32> inreg, i32, i32, i32) diff --git a/llvm/test/CodeGen/AMDGPU/livevars-implicitdef.mir b/llvm/test/CodeGen/AMDGPU/livevars-implicitdef.mir new file mode 100644 index 0000000000000..18aeb2527b1a3 --- /dev/null +++ b/llvm/test/CodeGen/AMDGPU/livevars-implicitdef.mir @@ -0,0 +1,91 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5 +# RUN: llc -mtriple=amdgcn --run-pass=livevars -o - %s | FileCheck %s +--- +# Check that super register is defined for an sgpr copy. +name: sgpr_copy +tracksRegLiveness: true +body: | + bb.0: + + ; CHECK-LABEL: name: sgpr_copy + ; CHECK: %sval:sreg_32 = S_MOV_B32 0 + ; CHECK-NEXT: $sgpr0 = COPY %sval + ; CHECK-NEXT: $sgpr1 = COPY %sval + ; CHECK-NEXT: $sgpr2 = COPY %sval + ; CHECK-NEXT: $sgpr3 = COPY killed %sval + ; CHECK-NEXT: SI_RETURN implicit killed $sgpr0_sgpr1_sgpr2_sgpr3 + %sval:sreg_32 = S_MOV_B32 0 + + $sgpr0 = COPY %sval + $sgpr1 = COPY %sval + $sgpr2 = COPY %sval + $sgpr3 = COPY %sval + SI_RETURN implicit $sgpr0_sgpr1_sgpr2_sgpr3 + +... +--- +# Check that super register is defined for a vgpr vector copy. +name: vgpr_copy +tracksRegLiveness: true +body: | + bb.0: + + ; CHECK-LABEL: name: vgpr_copy + ; CHECK: %vval:vgpr_32 = V_MOV_B32_e32 0, implicit $exec + ; CHECK-NEXT: $vgpr0 = COPY %vval + ; CHECK-NEXT: $vgpr1 = COPY %vval + ; CHECK-NEXT: $vgpr2 = COPY %vval + ; CHECK-NEXT: $vgpr3 = COPY killed %vval + ; CHECK-NEXT: dead [[COPY:%[0-9]+]]:vgpr_32 = COPY killed $vgpr0_vgpr1_vgpr2_vgpr3 + %vval:vgpr_32 = V_MOV_B32_e32 0, implicit $exec + + $vgpr0 = COPY %vval + $vgpr1 = COPY %vval + $vgpr2 = COPY %vval + $vgpr3 = COPY %vval + %0:vgpr_32 = COPY $vgpr0_vgpr1_vgpr2_vgpr3 + +... +--- +# Check that super register is defined when there is a hole. +name: sgpr_copy_hole +tracksRegLiveness: true +body: | + bb.0: + ; CHECK-LABEL: name: sgpr_copy_hole + ; CHECK: %sval:sreg_32 = S_MOV_B32 0 + ; CHECK-NEXT: $sgpr0 = COPY %sval + ; CHECK-NEXT: $sgpr2 = COPY %sval + ; CHECK-NEXT: $sgpr3 = COPY killed %sval + ; CHECK-NEXT: SI_RETURN implicit killed $sgpr0_sgpr1_sgpr2_sgpr3 + %sval:sreg_32 = S_MOV_B32 0 + + $sgpr0 = COPY %sval + $sgpr2 = COPY %sval + $sgpr3 = COPY %sval + SI_RETURN implicit $sgpr0_sgpr1_sgpr2_sgpr3 + +... +--- +# Check that super register is defined when a pair interrupts the sequence. +name: vgpr_copy_pair +tracksRegLiveness: true +body: | + bb.0: + ; CHECK-LABEL: name: vgpr_copy_pair + ; CHECK: %vval:vgpr_32 = V_MOV_B32_e32 0, implicit $exec + ; CHECK-NEXT: $vgpr0 = COPY %vval + ; CHECK-NEXT: $vgpr1 = COPY %vval + ; CHECK-NEXT: $vgpr2 = COPY %vval + ; CHECK-NEXT: $vgpr3 = COPY killed %vval + ; CHECK-NEXT: dead [[COPY:%[0-9]+]]:vgpr_32 = COPY $vgpr1_vgpr2 + ; CHECK-NEXT: dead [[COPY1:%[0-9]+]]:vgpr_32 = COPY killed $vgpr0_vgpr1_vgpr2_vgpr3 + %vval:vgpr_32 = V_MOV_B32_e32 0, implicit $exec + + $vgpr0 = COPY %vval + $vgpr1 = COPY %vval + $vgpr2 = COPY %vval + $vgpr3 = COPY %vval + %0:vgpr_32 = COPY $vgpr1_vgpr2 + %1:vgpr_32 = COPY $vgpr0_vgpr1_vgpr2_vgpr3 +...