Index: lib/CodeGen/ExpandPostRAPseudos.cpp =================================================================== --- lib/CodeGen/ExpandPostRAPseudos.cpp +++ lib/CodeGen/ExpandPostRAPseudos.cpp @@ -142,8 +142,9 @@ MachineOperand &DstMO = MI->getOperand(0); MachineOperand &SrcMO = MI->getOperand(1); - if (SrcMO.getReg() == DstMO.getReg()) { - DEBUG(dbgs() << "identity copy: " << *MI); + bool IdentityCopy = (SrcMO.getReg() == DstMO.getReg()); + if (IdentityCopy || SrcMO.isUndef()) { + DEBUG(dbgs() << (IdentityCopy ? "identity copy: " : "undef copy: ") << *MI); // No need to insert an identity copy instruction, but replace with a KILL // if liveness is changed. if (SrcMO.isUndef() || MI->getNumOperands() > 2) { Index: test/CodeGen/SystemZ/lower-copy-undef-src.mir =================================================================== --- /dev/null +++ test/CodeGen/SystemZ/lower-copy-undef-src.mir @@ -0,0 +1,191 @@ +# RUN: llc -mtriple=s390x-linux-gnu -mcpu=z13 -verify-machineinstrs -run-pass=postrapseudos -o - %s | FileCheck %s +# +# Test that a COPY with an undef source operand gets handled like an identity +# copy rather than lowered into a target instruction with the undef flag +# dropped. + +# CHECK: define void + +--- | + define void @autogen_SD13338(i8*, i32*, i64*, i32, i64, i8) #0 { + BB: + %L5 = load <4 x i32>, <4 x i32>* undef + %L30 = load i8, i8* %0 + %B42 = sdiv i64 undef, undef + %L45 = load <4 x i32>, <4 x i32>* undef + br label %CF284 + + CF284: ; preds = %CF284, %BB + %L52 = load i8, i8* %0 + %B56 = udiv i64 %B42, %4 + %Sl57 = select i1 true, i1 undef, i1 undef + br i1 %Sl57, label %CF284, label %CF294 + + CF294: ; preds = %CF284 + br label %CF + + CF: ; preds = %CF, %CF294 + %L94 = load i8, i8* %0 + store i8 0, i8* %0 + %B127 = urem <4 x i32> %L5, %L45 + %E132 = extractelement <4 x i1> zeroinitializer, i32 0 + br i1 %E132, label %CF, label %CF273 + + CF273: ; preds = %CF + %B150 = lshr i64 undef, %B56 + %B212 = xor <4 x i32> %L5, %B127 + %PC = bitcast i64* %2 to i8* + store i8 %L30, i8* %PC + store i8 %L94, i8* %PC + br label %CF275 + + CF275: ; preds = %CF275, %CF273 + %6 = bitcast i64* %2 to i8* + store i8 %L52, i8* %6 + br label %CF275 + } + + attributes #0 = { "target-cpu"="z13" } + +... +--- +name: autogen_SD13338 +alignment: 2 +exposesReturnsTwice: false +noVRegs: true +legalized: false +regBankSelected: false +selected: false +tracksRegLiveness: true +liveins: + - { reg: '%r2d' } + - { reg: '%r4d' } + - { reg: '%r6d' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 16 + offsetAdjustment: 0 + maxAlignment: 8 + adjustsStack: false + hasCalls: false + maxCallFrameSize: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false +fixedStack: + - { id: 0, type: spill-slot, offset: 120, size: 8, alignment: 8, callee-saved-register: '%r15d' } + - { id: 1, type: spill-slot, offset: 112, size: 8, alignment: 8, callee-saved-register: '%r14d' } + - { id: 2, type: spill-slot, offset: 104, size: 8, alignment: 8, callee-saved-register: '%r13d' } + - { id: 3, type: spill-slot, offset: 96, size: 8, alignment: 8, callee-saved-register: '%r12d' } + - { id: 4, type: spill-slot, offset: 88, size: 8, alignment: 8, callee-saved-register: '%r11d' } + - { id: 5, type: spill-slot, offset: 80, size: 8, alignment: 8, callee-saved-register: '%r10d' } + - { id: 6, type: spill-slot, offset: 72, size: 8, alignment: 8, callee-saved-register: '%r9d' } + - { id: 7, type: spill-slot, offset: 64, size: 8, alignment: 8, callee-saved-register: '%r8d' } + - { id: 8, type: spill-slot, offset: 56, size: 8, alignment: 8, callee-saved-register: '%r7d' } + - { id: 9, type: spill-slot, offset: 48, size: 8, alignment: 8, callee-saved-register: '%r6d' } + - { id: 10, offset: 0, size: 4, alignment: 8, isImmutable: true, isAliased: false } +stack: + - { id: 0, type: spill-slot, offset: -176, size: 16, alignment: 8 } +body: | + bb.0.BB: + successors: %bb.1.CF284(0x80000000) + liveins: %r2d, %r4d, %r6d, %r15d, %r7d, %r8d, %r9d, %r10d, %r11d, %r12d, %r13d, %r14d + + STMG %r6d, killed %r15d, %r15d, 48, implicit killed %r7d, implicit killed %r8d, implicit killed %r9d, implicit killed %r10d, implicit killed %r11d, implicit killed %r12d, implicit killed %r13d, implicit killed %r14d + CFI_INSTRUCTION offset %r6d, -112 + CFI_INSTRUCTION offset %r7d, -104 + CFI_INSTRUCTION offset %r8d, -96 + CFI_INSTRUCTION offset %r9d, -88 + CFI_INSTRUCTION offset %r10d, -80 + CFI_INSTRUCTION offset %r11d, -72 + CFI_INSTRUCTION offset %r12d, -64 + CFI_INSTRUCTION offset %r13d, -56 + CFI_INSTRUCTION offset %r14d, -48 + CFI_INSTRUCTION offset %r15d, -40 + %r15d = AGHI %r15d, -176, implicit-def dead %cc + CFI_INSTRUCTION def_cfa_offset 336 + %v0 = VL undef %r1d, 0, _ :: (load 16 from `<4 x i32>* undef`, align 8) + %r5h = LBMux %r2d, 0, _ :: (load 1 from %ir.0) + %v1 = COPY %v0 + %r1d = LLILL 0 + %r12d = COPY killed %r1d, implicit-def %r12q + %r13d = COPY undef %r0d, implicit killed %r12q, implicit-def %r12q + %r1l = LHIMux 0 + + bb.1.CF284: + successors: %bb.1.CF284(0x7c000000), %bb.2.CF294(0x04000000) + liveins: %v0, %v1, %r2d, %r4d, %r6d, %r5h, %r1l, %r12q + + %r10q = COPY %r12q + dead %r10q = DLGR killed %r10q, %r6d + CHIMux %r1l, 0, implicit-def %cc + BRC 14, 6, %bb.1.CF284, implicit killed %cc + + bb.2.CF294: + successors: %bb.3.CF(0x80000000) + liveins: %v0, %v1, %r2d, %r4d, %r5h + + %r1l = LBMux %r2d, 0, _ :: (load 1 from %ir.0) + %r3d = LLILL 0 + %r12d = COPY %r3d, implicit-def %r12q + ST128 killed %r12q, %r15d, 160, _ :: (store 16 into %stack.0, align 8) + %r10d = COPY %r3d, implicit-def %r10q + %r8d = COPY %r3d, implicit-def %r8q + %r6d = COPY killed %r3d, implicit-def %r6q + %r5l = LHIMux 0 + + bb.3.CF: + successors: %bb.3.CF(0x7c000000), %bb.4.CF273(0x04000000) + liveins: %v0, %v1, %r2d, %r4d, %r5h, %r1l, %r5l, %r6q, %r8q, %r10q + + %r3l = LBMux %r2d, 0, _ :: (load 1 from %ir.0) + MVI %r2d, 0, 0 :: (store 1 into %ir.0) + %r14d = VLGVF %v0, _, 3 + %r14l = KILL %r14l, implicit killed %r14d + %r0d = VLGVF %v1, _, 3 + %r0l = KILL %r0l, implicit killed %r0d + %r12q = L128 %r15d, 160, _ :: (load 16 from %stack.0, align 8) + %r13l = COPY killed %r0l, implicit killed %r12q, implicit-def %r12q + dead %r12q = DLR killed %r12q, killed %r14l + %r0d = VLGVF %v0, _, 1 + %r0l = KILL %r0l, implicit killed %r0d + %r14d = VLGVF %v1, _, 1 + %r14l = KILL %r14l, implicit killed %r14d + %r12q = COPY %r10q + %r13l = COPY killed %r14l, implicit killed %r12q, implicit-def %r12q + dead %r12q = DLR killed %r12q, killed %r0l + %r0d = VLGVF %v0, _, 0 + %r0l = KILL %r0l, implicit killed %r0d + %r14d = VLGVF %v1, _, 0 + %r14l = KILL %r14l, implicit killed %r14d + %r12q = COPY %r8q + %r13l = COPY killed %r14l, implicit killed %r12q, implicit-def %r12q + dead %r12q = DLR killed %r12q, killed %r0l + %r0d = VLGVF %v0, _, 2 + %r0l = KILL %r0l, implicit killed %r0d + %r14d = VLGVF %v1, _, 2 + %r14l = KILL %r14l, implicit killed %r14d + %r12q = COPY %r6q + %r13l = COPY killed %r14l, implicit killed %r12q, implicit-def %r12q + dead %r12q = DLR killed %r12q, killed %r0l + CHIMux %r5l, 0, implicit-def %cc + BRC 14, 6, %bb.3.CF, implicit killed %cc + + bb.4.CF273: + successors: %bb.5.CF275(0x80000000) + liveins: %r4d, %r5h, %r1l, %r3l + + STCMux killed %r5h, %r4d, 0, _ :: (store 1 into %ir.PC) + STCMux killed %r3l, %r4d, 0, _ :: (store 1 into %ir.PC) + + bb.5.CF275: + successors: %bb.5.CF275(0x80000000) + liveins: %r4d, %r1l + + STCMux %r1l, %r4d, 0, _ :: (store 1 into %ir.6) + J %bb.5.CF275 + +...