Index: lib/Target/SystemZ/SystemZRegisterInfo.h =================================================================== --- lib/Target/SystemZ/SystemZRegisterInfo.h +++ lib/Target/SystemZ/SystemZRegisterInfo.h @@ -59,6 +59,14 @@ void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj, unsigned FIOperandNum, RegScavenger *RS) const override; + bool shouldCoalesce(MachineInstr *MI, + const TargetRegisterClass *SrcRC, + unsigned SubReg, + const TargetRegisterClass *DstRC, + unsigned DstSubReg, + const TargetRegisterClass *NewRC) const override; + + /// \brief SrcRC and DstRC will be morphed into NewRC if this returns true. unsigned getFrameRegister(const MachineFunction &MF) const override; }; Index: lib/Target/SystemZ/SystemZRegisterInfo.cpp =================================================================== --- lib/Target/SystemZ/SystemZRegisterInfo.cpp +++ lib/Target/SystemZ/SystemZRegisterInfo.cpp @@ -152,6 +152,21 @@ MI->getOperand(FIOperandNum + 1).ChangeToImmediate(Offset); } +bool SystemZRegisterInfo::shouldCoalesce(MachineInstr *MI, + const TargetRegisterClass *SrcRC, + unsigned SubReg, + const TargetRegisterClass *DstRC, + unsigned DstSubReg, + const TargetRegisterClass *NewRC) const { + // Avoid coalescing COPYs of subregs of a GR128 register to prevent + // regalloc running out of registers. + if (NewRC->hasSubClassEq(&SystemZ::GR128BitRegClass) && + (getRegSizeInBits(*SrcRC) <= 64 || getRegSizeInBits(*DstRC) <= 64)) + return false; + + return true; +} + unsigned SystemZRegisterInfo::getFrameRegister(const MachineFunction &MF) const { const SystemZFrameLowering *TFI = getFrameLowering(MF); Index: test/CodeGen/SystemZ/atomic-load-05.ll =================================================================== --- test/CodeGen/SystemZ/atomic-load-05.ll +++ test/CodeGen/SystemZ/atomic-load-05.ll @@ -5,7 +5,7 @@ define i128 @f1(i128 *%src) { ; CHECK-LABEL: f1: ; CHECK: lpq %r0, 0(%r3) -; CHECK-DAG: stg %r1, 8(%r2) +; CHECK-DAG: stg %r3, 8(%r2) ; CHECK-DAG: stg %r0, 0(%r2) ; CHECK: br %r14 %val = load atomic i128, i128 *%src seq_cst, align 16 Index: test/CodeGen/SystemZ/atomic-store-05.ll =================================================================== --- test/CodeGen/SystemZ/atomic-store-05.ll +++ test/CodeGen/SystemZ/atomic-store-05.ll @@ -4,9 +4,9 @@ define void @f1(i128 %val, i128 *%src) { ; CHECK-LABEL: f1: -; CHECK-DAG: lg %r1, 8(%r2) -; CHECK-DAG: lg %r0, 0(%r2) -; CHECK: stpq %r0, 0(%r3) +; CHECK-DAG: lg %r0, 8(%r2) +; CHECK-DAG: lg %r1, 0(%r2) +; CHECK: stpq %r4, 0(%r3) ; CHECK: bcr 1{{[45]}}, %r0 ; CHECK: br %r14 store atomic i128 %val, i128 *%src seq_cst, align 16 @@ -15,9 +15,9 @@ define void @f2(i128 %val, i128 *%src) { ; CHECK-LABEL: f2: -; CHECK-DAG: lg %r1, 8(%r2) -; CHECK-DAG: lg %r0, 0(%r2) -; CHECK: stpq %r0, 0(%r3) +; CHECK-DAG: lg %r0, 8(%r2) +; CHECK-DAG: lg %r1, 0(%r2) +; CHECK: stpq %r4, 0(%r3) ; CHECK-NOT: bcr 1{{[45]}}, %r0 ; CHECK: br %r14 store atomic i128 %val, i128 *%src monotonic, align 16 Index: test/CodeGen/SystemZ/cmpxchg-06.ll =================================================================== --- test/CodeGen/SystemZ/cmpxchg-06.ll +++ test/CodeGen/SystemZ/cmpxchg-06.ll @@ -5,13 +5,13 @@ ; Check CDSG without a displacement. define i128 @f1(i128 %cmp, i128 %swap, i128 *%src) { ; CHECK-LABEL: f1: -; CHECK-DAG: lg %r1, 8(%r4) -; CHECK-DAG: lg %r0, 0(%r4) -; CHECK-DAG: lg %r13, 8(%r3) -; CHECK-DAG: lg %r12, 0(%r3) -; CHECK: cdsg %r12, %r0, 0(%r5) -; CHECK-DAG: stg %r13, 8(%r2) -; CHECK-DAG: stg %r12, 0(%r2) +; CHECK-DAG: lg %r0, 8(%r4) +; CHECK-DAG: lg %r1, 0(%r4) +; CHECK-DAG: lg %r0, 8(%r3) +; CHECK-DAG: lg %r1, 0(%r3) +; CHECK: cdsg %r10, %r12, 0(%r5) +; CHECK-DAG: stg %r0, 8(%r2) +; CHECK-DAG: stg %r0, 0(%r2) ; CHECK: br %r14 %pairval = cmpxchg i128 *%src, i128 %cmp, i128 %swap seq_cst seq_cst %val = extractvalue { i128, i1 } %pairval, 0 Index: test/CodeGen/SystemZ/int-div-01.ll =================================================================== --- test/CodeGen/SystemZ/int-div-01.ll +++ test/CodeGen/SystemZ/int-div-01.ll @@ -7,9 +7,9 @@ ; Test register division. The result is in the second of the two registers. define void @f1(i32 *%dest, i32 %a, i32 %b) { ; CHECK-LABEL: f1: -; CHECK: lgfr %r1, %r3 +; CHECK: lgfr %r0, %r3 ; CHECK: dsgfr %r0, %r4 -; CHECK: st %r1, 0(%r2) +; CHECK: st %r0, 0(%r2) ; CHECK: br %r14 %div = sdiv i32 %a, %b store i32 %div, i32 *%dest @@ -19,7 +19,7 @@ ; Test register remainder. The result is in the first of the two registers. define void @f2(i32 *%dest, i32 %a, i32 %b) { ; CHECK-LABEL: f2: -; CHECK: lgfr %r1, %r3 +; CHECK: lgfr %r0, %r3 ; CHECK: dsgfr %r0, %r4 ; CHECK: st %r0, 0(%r2) ; CHECK: br %r14 @@ -32,9 +32,9 @@ define i32 @f3(i32 %dummy, i32 %a, i32 %b) { ; CHECK-LABEL: f3: ; CHECK-NOT: %r2 -; CHECK: lgfr %r3, %r3 +; CHECK: lgfr %r0, %r3 ; CHECK-NOT: %r2 -; CHECK: dsgfr %r2, %r4 +; CHECK: dsgfr %r0, %r4 ; CHECK-NOT: dsgfr ; CHECK: or %r2, %r3 ; CHECK: br %r14 @@ -48,8 +48,7 @@ ; is already sign-extended. define i32 @f4(i32 %dummy, i32 signext %a, i32 %b) { ; CHECK-LABEL: f4: -; CHECK-NOT: {{%r[234]}} -; CHECK: dsgfr %r2, %r4 +; CHECK: dsgfr %r0, %r4 ; CHECK-NOT: dsgfr ; CHECK: or %r2, %r3 ; CHECK: br %r14 @@ -63,9 +62,9 @@ define i32 @f5(i32 %dummy, i32 *%src, i32 %b) { ; CHECK-LABEL: f5: ; CHECK-NOT: %r2 -; CHECK: lgf %r3, 0(%r3) +; CHECK: lgf %r0, 0(%r3) ; CHECK-NOT: %r2 -; CHECK: dsgfr %r2, %r4 +; CHECK: dsgfr %r0, %r4 ; CHECK-NOT: dsgfr ; CHECK: or %r2, %r3 ; CHECK: br %r14 @@ -79,9 +78,9 @@ ; Test memory division with no displacement. define void @f6(i32 *%dest, i32 %a, i32 *%src) { ; CHECK-LABEL: f6: -; CHECK: lgfr %r1, %r3 +; CHECK: lgfr %r0, %r3 ; CHECK: dsgf %r0, 0(%r4) -; CHECK: st %r1, 0(%r2) +; CHECK: st %r0, 0(%r2) ; CHECK: br %r14 %b = load i32 , i32 *%src %div = sdiv i32 %a, %b @@ -92,7 +91,7 @@ ; Test memory remainder with no displacement. define void @f7(i32 *%dest, i32 %a, i32 *%src) { ; CHECK-LABEL: f7: -; CHECK: lgfr %r1, %r3 +; CHECK: lgfr %r0, %r3 ; CHECK: dsgf %r0, 0(%r4) ; CHECK: st %r0, 0(%r2) ; CHECK: br %r14 @@ -106,9 +105,9 @@ define i32 @f8(i32 %dummy, i32 %a, i32 *%src) { ; CHECK-LABEL: f8: ; CHECK-NOT: %r2 -; CHECK: lgfr %r3, %r3 +; CHECK: lgfr %r0, %r3 ; CHECK-NOT: %r2 -; CHECK: dsgf %r2, 0(%r4) +; CHECK: dsgf %r0, 0(%r4) ; CHECK-NOT: {{dsgf|dsgfr}} ; CHECK: or %r2, %r3 ; CHECK: br %r14 @@ -122,7 +121,7 @@ ; Check the high end of the DSGF range. define i32 @f9(i32 %dummy, i32 %a, i32 *%src) { ; CHECK-LABEL: f9: -; CHECK: dsgf %r2, 524284(%r4) +; CHECK: dsgf %r0, 524284(%r4) ; CHECK: br %r14 %ptr = getelementptr i32, i32 *%src, i64 131071 %b = load i32 , i32 *%ptr @@ -135,7 +134,7 @@ define i32 @f10(i32 %dummy, i32 %a, i32 *%src) { ; CHECK-LABEL: f10: ; CHECK: agfi %r4, 524288 -; CHECK: dsgf %r2, 0(%r4) +; CHECK: dsgf %r0, 0(%r4) ; CHECK: br %r14 %ptr = getelementptr i32, i32 *%src, i64 131072 %b = load i32 , i32 *%ptr @@ -146,7 +145,7 @@ ; Check the high end of the negative aligned DSGF range. define i32 @f11(i32 %dummy, i32 %a, i32 *%src) { ; CHECK-LABEL: f11: -; CHECK: dsgf %r2, -4(%r4) +; CHECK: dsgf %r0, -4(%r4) ; CHECK: br %r14 %ptr = getelementptr i32, i32 *%src, i64 -1 %b = load i32 , i32 *%ptr @@ -157,7 +156,7 @@ ; Check the low end of the DSGF range. define i32 @f12(i32 %dummy, i32 %a, i32 *%src) { ; CHECK-LABEL: f12: -; CHECK: dsgf %r2, -524288(%r4) +; CHECK: dsgf %r0, -524288(%r4) ; CHECK: br %r14 %ptr = getelementptr i32, i32 *%src, i64 -131072 %b = load i32 , i32 *%ptr @@ -170,7 +169,7 @@ define i32 @f13(i32 %dummy, i32 %a, i32 *%src) { ; CHECK-LABEL: f13: ; CHECK: agfi %r4, -524292 -; CHECK: dsgf %r2, 0(%r4) +; CHECK: dsgf %r0, 0(%r4) ; CHECK: br %r14 %ptr = getelementptr i32, i32 *%src, i64 -131073 %b = load i32 , i32 *%ptr @@ -181,7 +180,7 @@ ; Check that DSGF allows an index. define i32 @f14(i32 %dummy, i32 %a, i64 %src, i64 %index) { ; CHECK-LABEL: f14: -; CHECK: dsgf %r2, 524287(%r5,%r4) +; CHECK: dsgf %r0, 524287(%r5,%r4) ; CHECK: br %r14 %add1 = add i64 %src, %index %add2 = add i64 %add1, 524287 @@ -197,7 +196,7 @@ ; CHECK-LABEL: f15: ; CHECK: l [[B:%r[0-9]+]], 0(%r3) ; CHECK: brasl %r14, foo@PLT -; CHECK: lgfr %r1, %r2 +; CHECK: lgfr %r0, %r2 ; CHECK: dsgfr %r0, [[B]] ; CHECK: br %r14 %b = load i32 , i32 *%src Index: test/CodeGen/SystemZ/int-div-02.ll =================================================================== --- test/CodeGen/SystemZ/int-div-02.ll +++ test/CodeGen/SystemZ/int-div-02.ll @@ -8,10 +8,9 @@ define void @f1(i32 %dummy, i32 %a, i32 %b, i32 *%dest) { ; CHECK-LABEL: f1: ; CHECK-NOT: %r3 -; CHECK: {{llill|lhi}} %r2, 0 -; CHECK-NOT: %r3 -; CHECK: dlr %r2, %r4 -; CHECK: st %r3, 0(%r5) +; CHECK: {{llill|lhi}} %r0, 0 +; CHECK: dlr %r0, %r4 +; CHECK: st %r0, 0(%r5) ; CHECK: br %r14 %div = udiv i32 %a, %b store i32 %div, i32 *%dest @@ -22,10 +21,9 @@ define void @f2(i32 %dummy, i32 %a, i32 %b, i32 *%dest) { ; CHECK-LABEL: f2: ; CHECK-NOT: %r3 -; CHECK: {{llill|lhi}} %r2, 0 -; CHECK-NOT: %r3 -; CHECK: dlr %r2, %r4 -; CHECK: st %r2, 0(%r5) +; CHECK: {{llill|lhi}} %r0, 0 +; CHECK: dlr %r0, %r4 +; CHECK: st %r0, 0(%r5) ; CHECK: br %r14 %rem = urem i32 %a, %b store i32 %rem, i32 *%dest @@ -36,9 +34,8 @@ define i32 @f3(i32 %dummy1, i32 %a, i32 %b) { ; CHECK-LABEL: f3: ; CHECK-NOT: %r3 -; CHECK: {{llill|lhi}} %r2, 0 -; CHECK-NOT: %r3 -; CHECK: dlr %r2, %r4 +; CHECK: {{llill|lhi}} %r0, 0 +; CHECK: dlr %r0, %r4 ; CHECK-NOT: dlr ; CHECK: or %r2, %r3 ; CHECK: br %r14 @@ -52,10 +49,9 @@ define void @f4(i32 %dummy, i32 %a, i32 *%src, i32 *%dest) { ; CHECK-LABEL: f4: ; CHECK-NOT: %r3 -; CHECK: {{llill|lhi}} %r2, 0 -; CHECK-NOT: %r3 -; CHECK: dl %r2, 0(%r4) -; CHECK: st %r3, 0(%r5) +; CHECK: {{llill|lhi}} %r0, 0 +; CHECK: dl %r0, 0(%r4) +; CHECK: st %r0, 0(%r5) ; CHECK: br %r14 %b = load i32 , i32 *%src %div = udiv i32 %a, %b @@ -67,10 +63,9 @@ define void @f5(i32 %dummy, i32 %a, i32 *%src, i32 *%dest) { ; CHECK-LABEL: f5: ; CHECK-NOT: %r3 -; CHECK: {{llill|lhi}} %r2, 0 -; CHECK-NOT: %r3 -; CHECK: dl %r2, 0(%r4) -; CHECK: st %r2, 0(%r5) +; CHECK: {{llill|lhi}} %r0, 0 +; CHECK: dl %r0, 0(%r4) +; CHECK: st %r0, 0(%r5) ; CHECK: br %r14 %b = load i32 , i32 *%src %rem = urem i32 %a, %b @@ -82,9 +77,8 @@ define i32 @f6(i32 %dummy, i32 %a, i32 *%src) { ; CHECK-LABEL: f6: ; CHECK-NOT: %r3 -; CHECK: {{llill|lhi}} %r2, 0 -; CHECK-NOT: %r3 -; CHECK: dl %r2, 0(%r4) +; CHECK: {{llill|lhi}} %r0, 0 +; CHECK: dl %r0, 0(%r4) ; CHECK-NOT: {{dl|dlr}} ; CHECK: or %r2, %r3 ; CHECK: br %r14 @@ -98,7 +92,7 @@ ; Check the high end of the DL range. define i32 @f7(i32 %dummy, i32 %a, i32 *%src) { ; CHECK-LABEL: f7: -; CHECK: dl %r2, 524284(%r4) +; CHECK: dl %r0, 524284(%r4) ; CHECK: br %r14 %ptr = getelementptr i32, i32 *%src, i64 131071 %b = load i32 , i32 *%ptr @@ -111,7 +105,7 @@ define i32 @f8(i32 %dummy, i32 %a, i32 *%src) { ; CHECK-LABEL: f8: ; CHECK: agfi %r4, 524288 -; CHECK: dl %r2, 0(%r4) +; CHECK: dl %r0, 0(%r4) ; CHECK: br %r14 %ptr = getelementptr i32, i32 *%src, i64 131072 %b = load i32 , i32 *%ptr @@ -122,7 +116,7 @@ ; Check the high end of the negative aligned DL range. define i32 @f9(i32 %dummy, i32 %a, i32 *%src) { ; CHECK-LABEL: f9: -; CHECK: dl %r2, -4(%r4) +; CHECK: dl %r0, -4(%r4) ; CHECK: br %r14 %ptr = getelementptr i32, i32 *%src, i64 -1 %b = load i32 , i32 *%ptr @@ -133,7 +127,7 @@ ; Check the low end of the DL range. define i32 @f10(i32 %dummy, i32 %a, i32 *%src) { ; CHECK-LABEL: f10: -; CHECK: dl %r2, -524288(%r4) +; CHECK: dl %r0, -524288(%r4) ; CHECK: br %r14 %ptr = getelementptr i32, i32 *%src, i64 -131072 %b = load i32 , i32 *%ptr @@ -146,7 +140,7 @@ define i32 @f11(i32 %dummy, i32 %a, i32 *%src) { ; CHECK-LABEL: f11: ; CHECK: agfi %r4, -524292 -; CHECK: dl %r2, 0(%r4) +; CHECK: dl %r0, 0(%r4) ; CHECK: br %r14 %ptr = getelementptr i32, i32 *%src, i64 -131073 %b = load i32 , i32 *%ptr @@ -157,7 +151,7 @@ ; Check that DL allows an index. define i32 @f12(i32 %dummy, i32 %a, i64 %src, i64 %index) { ; CHECK-LABEL: f12: -; CHECK: dl %r2, 524287(%r5,%r4) +; CHECK: dl %r0, 524287(%r5,%r4) ; CHECK: br %r14 %add1 = add i64 %src, %index %add2 = add i64 %add1, 524287 Index: test/CodeGen/SystemZ/int-div-03.ll =================================================================== --- test/CodeGen/SystemZ/int-div-03.ll +++ test/CodeGen/SystemZ/int-div-03.ll @@ -8,9 +8,8 @@ ; Test register division. The result is in the second of the two registers. define void @f1(i64 %dummy, i64 %a, i32 %b, i64 *%dest) { ; CHECK-LABEL: f1: -; CHECK-NOT: {{%r[234]}} -; CHECK: dsgfr %r2, %r4 -; CHECK: stg %r3, 0(%r5) +; CHECK: dsgfr %r0, %r4 +; CHECK: stg %r0, 0(%r5) ; CHECK: br %r14 %bext = sext i32 %b to i64 %div = sdiv i64 %a, %bext @@ -21,9 +20,8 @@ ; Test register remainder. The result is in the first of the two registers. define void @f2(i64 %dummy, i64 %a, i32 %b, i64 *%dest) { ; CHECK-LABEL: f2: -; CHECK-NOT: {{%r[234]}} -; CHECK: dsgfr %r2, %r4 -; CHECK: stg %r2, 0(%r5) +; CHECK: dsgfr %r0, %r4 +; CHECK: stg %r0, 0(%r5) ; CHECK: br %r14 %bext = sext i32 %b to i64 %rem = srem i64 %a, %bext @@ -34,8 +32,7 @@ ; Test that division and remainder use a single instruction. define i64 @f3(i64 %dummy, i64 %a, i32 %b) { ; CHECK-LABEL: f3: -; CHECK-NOT: {{%r[234]}} -; CHECK: dsgfr %r2, %r4 +; CHECK: dsgfr %r0, %r4 ; CHECK: ogr %r2, %r3 ; CHECK: br %r14 %bext = sext i32 %b to i64 @@ -71,9 +68,8 @@ ; Test memory division with no displacement. define void @f6(i64 %dummy, i64 %a, i32 *%src, i64 *%dest) { ; CHECK-LABEL: f6: -; CHECK-NOT: {{%r[234]}} -; CHECK: dsgf %r2, 0(%r4) -; CHECK: stg %r3, 0(%r5) +; CHECK: dsgf %r0, 0(%r4) +; CHECK: stg %r0, 0(%r5) ; CHECK: br %r14 %b = load i32 , i32 *%src %bext = sext i32 %b to i64 @@ -85,9 +81,8 @@ ; Test memory remainder with no displacement. define void @f7(i64 %dummy, i64 %a, i32 *%src, i64 *%dest) { ; CHECK-LABEL: f7: -; CHECK-NOT: {{%r[234]}} -; CHECK: dsgf %r2, 0(%r4) -; CHECK: stg %r2, 0(%r5) +; CHECK: dsgf %r0, 0(%r4) +; CHECK: stg %r0, 0(%r5) ; CHECK: br %r14 %b = load i32 , i32 *%src %bext = sext i32 %b to i64 @@ -99,8 +94,7 @@ ; Test both memory division and memory remainder. define i64 @f8(i64 %dummy, i64 %a, i32 *%src) { ; CHECK-LABEL: f8: -; CHECK-NOT: {{%r[234]}} -; CHECK: dsgf %r2, 0(%r4) +; CHECK: dsgf %r0, 0(%r4) ; CHECK-NOT: {{dsgf|dsgfr}} ; CHECK: ogr %r2, %r3 ; CHECK: br %r14 @@ -115,7 +109,7 @@ ; Check the high end of the DSGF range. define i64 @f9(i64 %dummy, i64 %a, i32 *%src) { ; CHECK-LABEL: f9: -; CHECK: dsgf %r2, 524284(%r4) +; CHECK: dsgf %r0, 524284(%r4) ; CHECK: br %r14 %ptr = getelementptr i32, i32 *%src, i64 131071 %b = load i32 , i32 *%ptr @@ -129,7 +123,7 @@ define i64 @f10(i64 %dummy, i64 %a, i32 *%src) { ; CHECK-LABEL: f10: ; CHECK: agfi %r4, 524288 -; CHECK: dsgf %r2, 0(%r4) +; CHECK: dsgf %r0, 0(%r4) ; CHECK: br %r14 %ptr = getelementptr i32, i32 *%src, i64 131072 %b = load i32 , i32 *%ptr @@ -141,7 +135,7 @@ ; Check the high end of the negative aligned DSGF range. define i64 @f11(i64 %dummy, i64 %a, i32 *%src) { ; CHECK-LABEL: f11: -; CHECK: dsgf %r2, -4(%r4) +; CHECK: dsgf %r0, -4(%r4) ; CHECK: br %r14 %ptr = getelementptr i32, i32 *%src, i64 -1 %b = load i32 , i32 *%ptr @@ -153,7 +147,7 @@ ; Check the low end of the DSGF range. define i64 @f12(i64 %dummy, i64 %a, i32 *%src) { ; CHECK-LABEL: f12: -; CHECK: dsgf %r2, -524288(%r4) +; CHECK: dsgf %r0, -524288(%r4) ; CHECK: br %r14 %ptr = getelementptr i32, i32 *%src, i64 -131072 %b = load i32 , i32 *%ptr @@ -167,7 +161,7 @@ define i64 @f13(i64 %dummy, i64 %a, i32 *%src) { ; CHECK-LABEL: f13: ; CHECK: agfi %r4, -524292 -; CHECK: dsgf %r2, 0(%r4) +; CHECK: dsgf %r0, 0(%r4) ; CHECK: br %r14 %ptr = getelementptr i32, i32 *%src, i64 -131073 %b = load i32 , i32 *%ptr @@ -179,7 +173,7 @@ ; Check that DSGF allows an index. define i64 @f14(i64 %dummy, i64 %a, i64 %src, i64 %index) { ; CHECK-LABEL: f14: -; CHECK: dsgf %r2, 524287(%r5,%r4) +; CHECK: dsgf %r0, 524287(%r5,%r4) ; CHECK: br %r14 %add1 = add i64 %src, %index %add2 = add i64 %add1, 524287 Index: test/CodeGen/SystemZ/int-div-04.ll =================================================================== --- test/CodeGen/SystemZ/int-div-04.ll +++ test/CodeGen/SystemZ/int-div-04.ll @@ -7,9 +7,8 @@ ; Testg register division. The result is in the second of the two registers. define void @f1(i64 %dummy, i64 %a, i64 %b, i64 *%dest) { ; CHECK-LABEL: f1: -; CHECK-NOT: {{%r[234]}} -; CHECK: dsgr %r2, %r4 -; CHECK: stg %r3, 0(%r5) +; CHECK: dsgr %r0, %r4 +; CHECK: stg %r0, 0(%r5) ; CHECK: br %r14 %div = sdiv i64 %a, %b store i64 %div, i64 *%dest @@ -19,9 +18,8 @@ ; Testg register remainder. The result is in the first of the two registers. define void @f2(i64 %dummy, i64 %a, i64 %b, i64 *%dest) { ; CHECK-LABEL: f2: -; CHECK-NOT: {{%r[234]}} -; CHECK: dsgr %r2, %r4 -; CHECK: stg %r2, 0(%r5) +; CHECK: dsgr %r0, %r4 +; CHECK: stg %r0, 0(%r5) ; CHECK: br %r14 %rem = srem i64 %a, %b store i64 %rem, i64 *%dest @@ -31,8 +29,7 @@ ; Testg that division and remainder use a single instruction. define i64 @f3(i64 %dummy1, i64 %a, i64 %b) { ; CHECK-LABEL: f3: -; CHECK-NOT: {{%r[234]}} -; CHECK: dsgr %r2, %r4 +; CHECK: dsgr %r0, %r4 ; CHECK-NOT: dsgr ; CHECK: ogr %r2, %r3 ; CHECK: br %r14 @@ -45,9 +42,8 @@ ; Testg memory division with no displacement. define void @f4(i64 %dummy, i64 %a, i64 *%src, i64 *%dest) { ; CHECK-LABEL: f4: -; CHECK-NOT: {{%r[234]}} -; CHECK: dsg %r2, 0(%r4) -; CHECK: stg %r3, 0(%r5) +; CHECK: dsg %r0, 0(%r4) +; CHECK: stg %r0, 0(%r5) ; CHECK: br %r14 %b = load i64 , i64 *%src %div = sdiv i64 %a, %b @@ -58,9 +54,8 @@ ; Testg memory remainder with no displacement. define void @f5(i64 %dummy, i64 %a, i64 *%src, i64 *%dest) { ; CHECK-LABEL: f5: -; CHECK-NOT: {{%r[234]}} -; CHECK: dsg %r2, 0(%r4) -; CHECK: stg %r2, 0(%r5) +; CHECK: dsg %r0, 0(%r4) +; CHECK: stg %r0, 0(%r5) ; CHECK: br %r14 %b = load i64 , i64 *%src %rem = srem i64 %a, %b @@ -71,8 +66,7 @@ ; Testg both memory division and memory remainder. define i64 @f6(i64 %dummy, i64 %a, i64 *%src) { ; CHECK-LABEL: f6: -; CHECK-NOT: {{%r[234]}} -; CHECK: dsg %r2, 0(%r4) +; CHECK: dsg %r0, 0(%r4) ; CHECK-NOT: {{dsg|dsgr}} ; CHECK: ogr %r2, %r3 ; CHECK: br %r14 @@ -86,7 +80,7 @@ ; Check the high end of the DSG range. define i64 @f7(i64 %dummy, i64 %a, i64 *%src) { ; CHECK-LABEL: f7: -; CHECK: dsg %r2, 524280(%r4) +; CHECK: dsg %r0, 524280(%r4) ; CHECK: br %r14 %ptr = getelementptr i64, i64 *%src, i64 65535 %b = load i64 , i64 *%ptr @@ -99,7 +93,7 @@ define i64 @f8(i64 %dummy, i64 %a, i64 *%src) { ; CHECK-LABEL: f8: ; CHECK: agfi %r4, 524288 -; CHECK: dsg %r2, 0(%r4) +; CHECK: dsg %r0, 0(%r4) ; CHECK: br %r14 %ptr = getelementptr i64, i64 *%src, i64 65536 %b = load i64 , i64 *%ptr @@ -110,7 +104,7 @@ ; Check the high end of the negative aligned DSG range. define i64 @f9(i64 %dummy, i64 %a, i64 *%src) { ; CHECK-LABEL: f9: -; CHECK: dsg %r2, -8(%r4) +; CHECK: dsg %r0, -8(%r4) ; CHECK: br %r14 %ptr = getelementptr i64, i64 *%src, i64 -1 %b = load i64 , i64 *%ptr @@ -121,7 +115,7 @@ ; Check the low end of the DSG range. define i64 @f10(i64 %dummy, i64 %a, i64 *%src) { ; CHECK-LABEL: f10: -; CHECK: dsg %r2, -524288(%r4) +; CHECK: dsg %r0, -524288(%r4) ; CHECK: br %r14 %ptr = getelementptr i64, i64 *%src, i64 -65536 %b = load i64 , i64 *%ptr @@ -134,7 +128,7 @@ define i64 @f11(i64 %dummy, i64 %a, i64 *%src) { ; CHECK-LABEL: f11: ; CHECK: agfi %r4, -524296 -; CHECK: dsg %r2, 0(%r4) +; CHECK: dsg %r0, 0(%r4) ; CHECK: br %r14 %ptr = getelementptr i64, i64 *%src, i64 -65537 %b = load i64 , i64 *%ptr @@ -145,7 +139,7 @@ ; Check that DSG allows an index. define i64 @f12(i64 %dummy, i64 %a, i64 %src, i64 %index) { ; CHECK-LABEL: f12: -; CHECK: dsg %r2, 524287(%r5,%r4) +; CHECK: dsg %r0, 524287(%r5,%r4) ; CHECK: br %r14 %add1 = add i64 %src, %index %add2 = add i64 %add1, 524287 Index: test/CodeGen/SystemZ/int-div-05.ll =================================================================== --- test/CodeGen/SystemZ/int-div-05.ll +++ test/CodeGen/SystemZ/int-div-05.ll @@ -8,10 +8,9 @@ define void @f1(i64 %dummy, i64 %a, i64 %b, i64 *%dest) { ; CHECK-LABEL: f1: ; CHECK-NOT: %r3 -; CHECK: {{llill|lghi}} %r2, 0 -; CHECK-NOT: %r3 -; CHECK: dlgr %r2, %r4 -; CHECK: stg %r3, 0(%r5) +; CHECK: {{llill|lghi}} %r0, 0 +; CHECK: dlgr %r0, %r4 +; CHECK: stg %r0, 0(%r5) ; CHECK: br %r14 %div = udiv i64 %a, %b store i64 %div, i64 *%dest @@ -22,10 +21,9 @@ define void @f2(i64 %dummy, i64 %a, i64 %b, i64 *%dest) { ; CHECK-LABEL: f2: ; CHECK-NOT: %r3 -; CHECK: {{llill|lghi}} %r2, 0 -; CHECK-NOT: %r3 -; CHECK: dlgr %r2, %r4 -; CHECK: stg %r2, 0(%r5) +; CHECK: {{llill|lghi}} %r0, 0 +; CHECK: dlgr %r0, %r4 +; CHECK: stg %r0, 0(%r5) ; CHECK: br %r14 %rem = urem i64 %a, %b store i64 %rem, i64 *%dest @@ -36,9 +34,8 @@ define i64 @f3(i64 %dummy1, i64 %a, i64 %b) { ; CHECK-LABEL: f3: ; CHECK-NOT: %r3 -; CHECK: {{llill|lghi}} %r2, 0 -; CHECK-NOT: %r3 -; CHECK: dlgr %r2, %r4 +; CHECK: {{llill|lghi}} %r0, 0 +; CHECK: dlgr %r0, %r4 ; CHECK-NOT: dlgr ; CHECK: ogr %r2, %r3 ; CHECK: br %r14 @@ -52,10 +49,9 @@ define void @f4(i64 %dummy, i64 %a, i64 *%src, i64 *%dest) { ; CHECK-LABEL: f4: ; CHECK-NOT: %r3 -; CHECK: {{llill|lghi}} %r2, 0 -; CHECK-NOT: %r3 -; CHECK: dlg %r2, 0(%r4) -; CHECK: stg %r3, 0(%r5) +; CHECK: {{llill|lghi}} %r0, 0 +; CHECK: dlg %r0, 0(%r4) +; CHECK: stg %r0, 0(%r5) ; CHECK: br %r14 %b = load i64 , i64 *%src %div = udiv i64 %a, %b @@ -67,10 +63,9 @@ define void @f5(i64 %dummy, i64 %a, i64 *%src, i64 *%dest) { ; CHECK-LABEL: f5: ; CHECK-NOT: %r3 -; CHECK: {{llill|lghi}} %r2, 0 -; CHECK-NOT: %r3 -; CHECK: dlg %r2, 0(%r4) -; CHECK: stg %r2, 0(%r5) +; CHECK: {{llill|lghi}} %r0, 0 +; CHECK: dlg %r0, 0(%r4) +; CHECK: stg %r0, 0(%r5) ; CHECK: br %r14 %b = load i64 , i64 *%src %rem = urem i64 %a, %b @@ -82,9 +77,8 @@ define i64 @f6(i64 %dummy, i64 %a, i64 *%src) { ; CHECK-LABEL: f6: ; CHECK-NOT: %r3 -; CHECK: {{llill|lghi}} %r2, 0 -; CHECK-NOT: %r3 -; CHECK: dlg %r2, 0(%r4) +; CHECK: {{llill|lghi}} %r0, 0 +; CHECK: dlg %r0, 0(%r4) ; CHECK-NOT: {{dlg|dlgr}} ; CHECK: ogr %r2, %r3 ; CHECK: br %r14 @@ -98,7 +92,7 @@ ; Check the high end of the DLG range. define i64 @f7(i64 %dummy, i64 %a, i64 *%src) { ; CHECK-LABEL: f7: -; CHECK: dlg %r2, 524280(%r4) +; CHECK: dlg %r0, 524280(%r4) ; CHECK: br %r14 %ptr = getelementptr i64, i64 *%src, i64 65535 %b = load i64 , i64 *%ptr @@ -111,7 +105,7 @@ define i64 @f8(i64 %dummy, i64 %a, i64 *%src) { ; CHECK-LABEL: f8: ; CHECK: agfi %r4, 524288 -; CHECK: dlg %r2, 0(%r4) +; CHECK: dlg %r0, 0(%r4) ; CHECK: br %r14 %ptr = getelementptr i64, i64 *%src, i64 65536 %b = load i64 , i64 *%ptr @@ -122,7 +116,7 @@ ; Check the high end of the negative aligned DLG range. define i64 @f9(i64 %dummy, i64 %a, i64 *%src) { ; CHECK-LABEL: f9: -; CHECK: dlg %r2, -8(%r4) +; CHECK: dlg %r0, -8(%r4) ; CHECK: br %r14 %ptr = getelementptr i64, i64 *%src, i64 -1 %b = load i64 , i64 *%ptr @@ -133,7 +127,7 @@ ; Check the low end of the DLG range. define i64 @f10(i64 %dummy, i64 %a, i64 *%src) { ; CHECK-LABEL: f10: -; CHECK: dlg %r2, -524288(%r4) +; CHECK: dlg %r0, -524288(%r4) ; CHECK: br %r14 %ptr = getelementptr i64, i64 *%src, i64 -65536 %b = load i64 , i64 *%ptr @@ -146,7 +140,7 @@ define i64 @f11(i64 %dummy, i64 %a, i64 *%src) { ; CHECK-LABEL: f11: ; CHECK: agfi %r4, -524296 -; CHECK: dlg %r2, 0(%r4) +; CHECK: dlg %r0, 0(%r4) ; CHECK: br %r14 %ptr = getelementptr i64, i64 *%src, i64 -65537 %b = load i64 , i64 *%ptr @@ -157,7 +151,7 @@ ; Check that DLG allows an index. define i64 @f12(i64 %dummy, i64 %a, i64 %src, i64 %index) { ; CHECK-LABEL: f12: -; CHECK: dlg %r2, 524287(%r5,%r4) +; CHECK: dlg %r0, 524287(%r5,%r4) ; CHECK: br %r14 %add1 = add i64 %src, %index %add2 = add i64 %add1, 524287 Index: test/CodeGen/SystemZ/int-div-06.ll =================================================================== --- test/CodeGen/SystemZ/int-div-06.ll +++ test/CodeGen/SystemZ/int-div-06.ll @@ -34,9 +34,9 @@ ; CHECK-DAG: srag [[REG:%r[0-5]]], %r3, 63 ; CHECK-DAG: ngr [[REG]], [[CONST]] ; CHECK-DAG: mlgr %r2, [[CONST]] -; CHECK: sgr %r2, [[REG]] -; CHECK: srlg [[RES1:%r[0-5]]], %r2, 63 -; CHECK: srag %r2, %r2, 15 +; CHECK: sgr [[REG2:%r[0-5]]], [[REG]] +; CHECK: srlg [[RES1:%r[0-5]]], [[REG2]], 63 +; CHECK: srag %r2, [[REG2]], 15 ; CHECK: agr %r2, [[RES1]] ; CHECK: br %r14 %b = sdiv i64 %a, 139968 @@ -49,7 +49,7 @@ ; CHECK: llihf [[CONST:%r[0-5]]], 1005497601 ; CHECK: oilf [[CONST]], 4251762321 ; CHECK: mlgr %r2, [[CONST]] -; CHECK: srlg %r2, %r2, 15 +; CHECK: srlg %r2, %r0, 15 ; CHECK: br %r14 %b = udiv i64 %a, 139968 ret i64 %b Index: test/CodeGen/SystemZ/int-mul-08.ll =================================================================== --- test/CodeGen/SystemZ/int-mul-08.ll +++ test/CodeGen/SystemZ/int-mul-08.ll @@ -7,9 +7,8 @@ ; Check zero-extended multiplication in which only the high part is used. define i64 @f1(i64 %dummy, i64 %a, i64 %b) { ; CHECK-LABEL: f1: -; CHECK-NOT: {{%r[234]}} -; CHECK: mlgr %r2, %r4 -; CHECK: br %r14 +; CHECK: mlgr %r0, %r4 +; CHECK: br %r14 %ax = zext i64 %a to i128 %bx = zext i64 %b to i128 %mulx = mul i128 %ax, %bx @@ -42,10 +41,9 @@ ; is used. define i64 @f3(i64 %dummy, i64 %a, i64 %b) { ; CHECK-LABEL: f3: -; CHECK-NOT: {{%r[234]}} -; CHECK: mlgr %r2, %r4 -; CHECK: srlg %r2, %r2, 3 -; CHECK: br %r14 +; CHECK: mlgr %r0, %r4 +; CHECK: srlg %r2, %r0, 3 +; CHECK: br %r14 %ax = zext i64 %a to i128 %bx = zext i64 %b to i128 %mulx = mul i128 %ax, %bx @@ -58,10 +56,9 @@ ; high and low halves. define i64 @f4(i64 %dummy, i64 %a, i64 %b) { ; CHECK-LABEL: f4: -; CHECK-NOT: {{%r[234]}} -; CHECK: mlgr %r2, %r4 -; CHECK: ogr %r2, %r3 -; CHECK: br %r14 +; CHECK: mlgr %r0, %r4 +; CHECK: ogr %r2, %r3 +; CHECK: br %r14 %ax = zext i64 %a to i128 %bx = zext i64 %b to i128 %mulx = mul i128 %ax, %bx @@ -75,9 +72,9 @@ ; Check division by a constant, which should use multiplication instead. define i64 @f5(i64 %dummy, i64 %a) { ; CHECK-LABEL: f5: -; CHECK: mlgr %r2, -; CHECK: srlg %r2, %r2, -; CHECK: br %r14 +; CHECK: mlgr %r2, %r0 +; CHECK: srlg %r2, %r0, 9 +; CHECK: br %r14 %res = udiv i64 %a, 1234 ret i64 %res } @@ -85,9 +82,8 @@ ; Check MLG with no displacement. define i64 @f6(i64 %dummy, i64 %a, i64 *%src) { ; CHECK-LABEL: f6: -; CHECK-NOT: {{%r[234]}} -; CHECK: mlg %r2, 0(%r4) -; CHECK: br %r14 +; CHECK: mlg %r0, 0(%r4) +; CHECK: br %r14 %b = load i64 , i64 *%src %ax = zext i64 %a to i128 %bx = zext i64 %b to i128 @@ -100,8 +96,8 @@ ; Check the high end of the aligned MLG range. define i64 @f7(i64 %dummy, i64 %a, i64 *%src) { ; CHECK-LABEL: f7: -; CHECK: mlg %r2, 524280(%r4) -; CHECK: br %r14 +; CHECK: mlg %r0, 524280(%r4) +; CHECK: br %r14 %ptr = getelementptr i64, i64 *%src, i64 65535 %b = load i64 , i64 *%ptr %ax = zext i64 %a to i128 @@ -117,7 +113,7 @@ define i64 @f8(i64 %dummy, i64 %a, i64 *%src) { ; CHECK-LABEL: f8: ; CHECK: agfi %r4, 524288 -; CHECK: mlg %r2, 0(%r4) +; CHECK: mlg %r0, 0(%r4) ; CHECK: br %r14 %ptr = getelementptr i64, i64 *%src, i64 65536 %b = load i64 , i64 *%ptr @@ -132,7 +128,7 @@ ; Check the high end of the negative aligned MLG range. define i64 @f9(i64 %dummy, i64 %a, i64 *%src) { ; CHECK-LABEL: f9: -; CHECK: mlg %r2, -8(%r4) +; CHECK: mlg %r0, -8(%r4) ; CHECK: br %r14 %ptr = getelementptr i64, i64 *%src, i64 -1 %b = load i64 , i64 *%ptr @@ -147,7 +143,7 @@ ; Check the low end of the MLG range. define i64 @f10(i64 %dummy, i64 %a, i64 *%src) { ; CHECK-LABEL: f10: -; CHECK: mlg %r2, -524288(%r4) +; CHECK: mlg %r0, -524288(%r4) ; CHECK: br %r14 %ptr = getelementptr i64, i64 *%src, i64 -65536 %b = load i64 , i64 *%ptr @@ -164,7 +160,7 @@ define i64 @f11(i64 *%dest, i64 %a, i64 *%src) { ; CHECK-LABEL: f11: ; CHECK: agfi %r4, -524296 -; CHECK: mlg %r2, 0(%r4) +; CHECK: mlg %r0, 0(%r4) ; CHECK: br %r14 %ptr = getelementptr i64, i64 *%src, i64 -65537 %b = load i64 , i64 *%ptr @@ -179,7 +175,7 @@ ; Check that MLG allows an index. define i64 @f12(i64 *%dest, i64 %a, i64 %src, i64 %index) { ; CHECK-LABEL: f12: -; CHECK: mlg %r2, 524287(%r5,%r4) +; CHECK: mlg %r0, 524287(%r5,%r4) ; CHECK: br %r14 %add1 = add i64 %src, %index %add2 = add i64 %add1, 524287 @@ -195,6 +191,7 @@ ; Check that multiplications of spilled values can use MLG rather than MLGR. define i64 @f13(i64 *%ptr0) { + ; CHECK-LABEL: f13: ; CHECK: brasl %r14, foo@PLT ; CHECK: mlg {{%r[0-9]+}}, 160(%r15) Index: test/CodeGen/SystemZ/int-mul-10.ll =================================================================== --- test/CodeGen/SystemZ/int-mul-10.ll +++ test/CodeGen/SystemZ/int-mul-10.ll @@ -1,3 +1,4 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; Test signed high-part i64->i128 multiplications on z14. ; ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z14 | FileCheck %s @@ -7,9 +8,10 @@ ; Check sign-extended multiplication in which only the high part is used. define i64 @f1(i64 %dummy, i64 %a, i64 %b) { ; CHECK-LABEL: f1: -; CHECK-NOT: {{%r[234]}} -; CHECK: mgrk %r2, %r3, %r4 -; CHECK: br %r14 +; CHECK: # BB#0: +; CHECK-NEXT: mgrk %r0, %r3, %r4 +; CHECK-NEXT: lgr %r2, %r0 +; CHECK-NEXT: br %r14 %ax = sext i64 %a to i128 %bx = sext i64 %b to i128 %mulx = mul i128 %ax, %bx @@ -22,10 +24,11 @@ ; is used. define i64 @f2(i64 %dummy, i64 %a, i64 %b) { ; CHECK-LABEL: f2: -; CHECK-NOT: {{%r[234]}} -; CHECK: mgrk [[REG:%r[0-9]+]], %r3, %r4 -; CHECK: srlg %r2, [[REG]], 3 -; CHECK: br %r14 +; CHECK: # BB#0: +; CHECK-NEXT: mgrk %r0, %r3, %r4 +; CHECK-NEXT: # kill: %R0D %R0D %R0Q +; CHECK-NEXT: srlg %r2, %r0, 3 +; CHECK-NEXT: br %r14 %ax = sext i64 %a to i128 %bx = sext i64 %b to i128 %mulx = mul i128 %ax, %bx @@ -38,10 +41,12 @@ ; high and low halves. define i64 @f3(i64 %dummy, i64 %a, i64 %b) { ; CHECK-LABEL: f3: -; CHECK-NOT: {{%r[234]}} -; CHECK: mgrk %r2, %r3, %r4 -; CHECK: ogr %r2, %r3 -; CHECK: br %r14 +; CHECK: # BB#0: +; CHECK-NEXT: mgrk %r0, %r3, %r4 +; CHECK-NEXT: lgr %r3, %r1 +; CHECK-NEXT: lgr %r2, %r0 +; CHECK-NEXT: ogr %r2, %r3 +; CHECK-NEXT: br %r14 %ax = sext i64 %a to i128 %bx = sext i64 %b to i128 %mulx = mul i128 %ax, %bx @@ -55,9 +60,11 @@ ; Check MG with no displacement. define i64 @f4(i64 %dummy, i64 %a, i64 *%src) { ; CHECK-LABEL: f4: -; CHECK-NOT: {{%r[234]}} -; CHECK: mg %r2, 0(%r4) -; CHECK: br %r14 +; CHECK: # BB#0: +; CHECK-NEXT: lgr %r1, %r3 +; CHECK-NEXT: mg %r0, 0(%r4) +; CHECK-NEXT: lgr %r2, %r0 +; CHECK-NEXT: br %r14 %b = load i64 , i64 *%src %ax = sext i64 %a to i128 %bx = sext i64 %b to i128 @@ -70,8 +77,11 @@ ; Check the high end of the aligned MG range. define i64 @f5(i64 %dummy, i64 %a, i64 *%src) { ; CHECK-LABEL: f5: -; CHECK: mg %r2, 524280(%r4) -; CHECK: br %r14 +; CHECK: # BB#0: +; CHECK-NEXT: lgr %r1, %r3 +; CHECK-NEXT: mg %r0, 524280(%r4) +; CHECK-NEXT: lgr %r2, %r0 +; CHECK-NEXT: br %r14 %ptr = getelementptr i64, i64 *%src, i64 65535 %b = load i64 , i64 *%ptr %ax = sext i64 %a to i128 @@ -86,9 +96,12 @@ ; Other sequences besides this one would be OK. define i64 @f6(i64 %dummy, i64 %a, i64 *%src) { ; CHECK-LABEL: f6: -; CHECK: agfi %r4, 524288 -; CHECK: mg %r2, 0(%r4) -; CHECK: br %r14 +; CHECK: # BB#0: +; CHECK-NEXT: lgr %r1, %r3 +; CHECK-NEXT: agfi %r4, 524288 +; CHECK-NEXT: mg %r0, 0(%r4) +; CHECK-NEXT: lgr %r2, %r0 +; CHECK-NEXT: br %r14 %ptr = getelementptr i64, i64 *%src, i64 65536 %b = load i64 , i64 *%ptr %ax = sext i64 %a to i128 @@ -102,8 +115,11 @@ ; Check the high end of the negative aligned MG range. define i64 @f7(i64 %dummy, i64 %a, i64 *%src) { ; CHECK-LABEL: f7: -; CHECK: mg %r2, -8(%r4) -; CHECK: br %r14 +; CHECK: # BB#0: +; CHECK-NEXT: lgr %r1, %r3 +; CHECK-NEXT: mg %r0, -8(%r4) +; CHECK-NEXT: lgr %r2, %r0 +; CHECK-NEXT: br %r14 %ptr = getelementptr i64, i64 *%src, i64 -1 %b = load i64 , i64 *%ptr %ax = sext i64 %a to i128 @@ -117,8 +133,11 @@ ; Check the low end of the MG range. define i64 @f8(i64 %dummy, i64 %a, i64 *%src) { ; CHECK-LABEL: f8: -; CHECK: mg %r2, -524288(%r4) -; CHECK: br %r14 +; CHECK: # BB#0: +; CHECK-NEXT: lgr %r1, %r3 +; CHECK-NEXT: mg %r0, -524288(%r4) +; CHECK-NEXT: lgr %r2, %r0 +; CHECK-NEXT: br %r14 %ptr = getelementptr i64, i64 *%src, i64 -65536 %b = load i64 , i64 *%ptr %ax = sext i64 %a to i128 @@ -133,9 +152,12 @@ ; Other sequences besides this one would be OK. define i64 @f9(i64 *%dest, i64 %a, i64 *%src) { ; CHECK-LABEL: f9: -; CHECK: agfi %r4, -524296 -; CHECK: mg %r2, 0(%r4) -; CHECK: br %r14 +; CHECK: # BB#0: +; CHECK-NEXT: lgr %r1, %r3 +; CHECK-NEXT: agfi %r4, -524296 +; CHECK-NEXT: mg %r0, 0(%r4) +; CHECK-NEXT: lgr %r2, %r0 +; CHECK-NEXT: br %r14 %ptr = getelementptr i64, i64 *%src, i64 -65537 %b = load i64 , i64 *%ptr %ax = sext i64 %a to i128 @@ -149,8 +171,11 @@ ; Check that MG allows an index. define i64 @f10(i64 *%dest, i64 %a, i64 %src, i64 %index) { ; CHECK-LABEL: f10: -; CHECK: mg %r2, 524287(%r5,%r4) -; CHECK: br %r14 +; CHECK: # BB#0: +; CHECK-NEXT: lgr %r1, %r3 +; CHECK-NEXT: mg %r0, 524287(%r5,%r4) +; CHECK-NEXT: lgr %r2, %r0 +; CHECK-NEXT: br %r14 %add1 = add i64 %src, %index %add2 = add i64 %add1, 524287 %ptr = inttoptr i64 %add2 to i64 * Index: test/CodeGen/SystemZ/pr32372.ll =================================================================== --- test/CodeGen/SystemZ/pr32372.ll +++ test/CodeGen/SystemZ/pr32372.ll @@ -4,10 +4,12 @@ define void @pr32372(i8*) { ; CHECK-LABEL: pr32372: ; CHECK: # BB#0: # %BB -; CHECK-NEXT: llc %r1, 0(%r2) +; CHECK-NEXT: llc %r0, 0(%r2) ; CHECK-NEXT: mvhhi 0(%r1), -3825 -; CHECK-NEXT: llill %r0, 0 -; CHECK-NEXT: dlr %r0, %r1 +; CHECK-NEXT: llill %r1, 0 +; CHECK-NEXT: lgr %r2, %r1 +; CHECK-NEXT: lgr %r3, %r0 +; CHECK-NEXT: dlr %r2, %r0 ; CHECK-NEXT: .LBB0_1: # %CF251 ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 ; CHECK-NEXT: j .LBB0_1 Index: test/CodeGen/SystemZ/regalloc-GR128.ll =================================================================== --- /dev/null +++ test/CodeGen/SystemZ/regalloc-GR128.ll @@ -0,0 +1,9 @@ +; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 -O3 -o /dev/null +; +; Test that regalloc does not run out of registers + +define void @test(i64 %dividend, i64 %divisor) { + %rem = urem i64 %dividend, %divisor + call void asm sideeffect "", "{r0},{r1},{r2},{r3},{r4},{r5},{r6},{r7},{r8},{r9},{r10},{r11},{r12},{r13},{r14}"(i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 0, i64 %rem) + ret void +}