[GlobalISel] Fix the artifact combiner to fold G_IMPLICIT_DEF properly

Summary:
GlobalISel generates incorrect code because the legalizer artifact
combiner assumes `G_[SZ]EXT (G_IMPLICIT_DEF)` is equivalent to
`G_IMPLICIT_DEF `.

Replace `G_[SZ]EXT (G_IMPLICIT_DEF)` with 0 because the top bits
will be 0 for G_ZEXT and 0/1 for the G_SEXT.

Reviewers: aditya_nandakumar, dsanders, aemerson, javed.absar

Reviewed By: aditya_nandakumar

Subscribers: rovka, kristof.beyls, llvm-commits

Differential Revision: https://reviews.llvm.org/D52996

llvm-svn: 344163
This commit is contained in:
Volkan Keles 2018-10-10 18:01:48 +00:00
parent 057784a263
commit da5578c5d0
4 changed files with 65 additions and 39 deletions

View File

@ -109,7 +109,7 @@ public:
return tryFoldImplicitDef(MI, DeadInsts);
}
/// Try to fold sb = EXTEND (G_IMPLICIT_DEF sa) -> sb = G_IMPLICIT_DEF
/// Try to fold G_[ASZ]EXT (G_IMPLICIT_DEF).
bool tryFoldImplicitDef(MachineInstr &MI,
SmallVectorImpl<MachineInstr *> &DeadInsts) {
unsigned Opcode = MI.getOpcode();
@ -119,13 +119,25 @@ public:
if (MachineInstr *DefMI = getOpcodeDef(TargetOpcode::G_IMPLICIT_DEF,
MI.getOperand(1).getReg(), MRI)) {
Builder.setInstr(MI);
unsigned DstReg = MI.getOperand(0).getReg();
LLT DstTy = MRI.getType(DstReg);
if (isInstUnsupported({TargetOpcode::G_IMPLICIT_DEF, {DstTy}}))
return false;
LLVM_DEBUG(dbgs() << ".. Combine EXT(IMPLICIT_DEF) " << MI;);
Builder.setInstr(MI);
Builder.buildInstr(TargetOpcode::G_IMPLICIT_DEF, DstReg);
if (Opcode == TargetOpcode::G_ANYEXT) {
// G_ANYEXT (G_IMPLICIT_DEF) -> G_IMPLICIT_DEF
if (isInstUnsupported({TargetOpcode::G_IMPLICIT_DEF, {DstTy}}))
return false;
LLVM_DEBUG(dbgs() << ".. Combine G_ANYEXT(G_IMPLICIT_DEF): " << MI;);
Builder.buildInstr(TargetOpcode::G_IMPLICIT_DEF, DstReg);
} else {
// G_[SZ]EXT (G_IMPLICIT_DEF) -> G_CONSTANT 0 because the top
// bits will be 0 for G_ZEXT and 0/1 for the G_SEXT.
if (isInstUnsupported({TargetOpcode::G_CONSTANT, {DstTy}}))
return false;
LLVM_DEBUG(dbgs() << ".. Combine G_[SZ]EXT(G_IMPLICIT_DEF): " << MI;);
Builder.buildConstant(DstReg, 0);
}
markInstAndDefDead(MI, *DefMI, DeadInsts);
return true;
}

View File

@ -82,9 +82,9 @@ body: |
; CHECK: $w0 = COPY [[ASHR2]](s32)
; CHECK: [[C6:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
; CHECK: [[TRUNC10:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64)
; CHECK: [[COPY5:%[0-9]+]]:_(s32) = COPY [[TRUNC3]]4(s32)
; CHECK: [[AND3:%[0-9]+]]:_(s32) = G_AND [[TRUNC3]]1, [[TRUNC3]]2
; CHECK: [[COPY6:%[0-9]+]]:_(s32) = COPY [[TRUNC3]]3(s32)
; CHECK: [[COPY5:%[0-9]+]]:_(s32) = COPY [[C6]](s32)
; CHECK: [[AND3:%[0-9]+]]:_(s32) = G_AND [[TRUNC10]], [[COPY5]]
; CHECK: [[COPY6:%[0-9]+]]:_(s32) = COPY [[AND3]](s32)
; CHECK: $w0 = COPY [[COPY6]](s32)
; CHECK: [[TRUNC11:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64)
; CHECK: $w0 = COPY [[TRUNC11]](s32)
@ -92,6 +92,12 @@ body: |
; CHECK: $w0 = COPY [[TRUNC12]](s32)
; CHECK: [[FPEXT:%[0-9]+]]:_(s64) = G_FPEXT [[TRUNC12]](s32)
; CHECK: $x0 = COPY [[FPEXT]](s64)
; CHECK: [[C7:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
; CHECK: $w0 = COPY [[C7]](s32)
; CHECK: [[C8:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
; CHECK: $w0 = COPY [[C8]](s32)
; CHECK: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
; CHECK: $w0 = COPY [[DEF]](s32)
%0(s64) = COPY $x0
%1(s1) = G_TRUNC %0
@ -140,4 +146,12 @@ body: |
$w0 = COPY %17
%18(s64) = G_FPEXT %17
$x0 = COPY %18
%24:_(s16) = G_IMPLICIT_DEF
%25:_(s32) = G_ZEXT %24(s16)
$w0 = COPY %25(s32)
%26:_(s32) = G_SEXT %24(s16)
$w0 = COPY %26(s32)
%27:_(s32) = G_ANYEXT %24(s16)
$w0 = COPY %27(s32)
...

View File

@ -288,12 +288,12 @@ body: |
liveins: $edi
; X32-LABEL: name: test_sext_i1toi8
; X32: [[DEF:%[0-9]+]]:_(s8) = G_IMPLICIT_DEF
; X32: $al = COPY [[DEF]](s8)
; X32: [[C:%[0-9]+]]:_(s8) = G_CONSTANT i8 0
; X32: $al = COPY [[C]](s8)
; X32: RET 0, implicit $al
; X64-LABEL: name: test_sext_i1toi8
; X64: [[DEF:%[0-9]+]]:_(s8) = G_IMPLICIT_DEF
; X64: $al = COPY [[DEF]](s8)
; X64: [[C:%[0-9]+]]:_(s8) = G_CONSTANT i8 0
; X64: $al = COPY [[C]](s8)
; X64: RET 0, implicit $al
%0(s1) = G_IMPLICIT_DEF
%1(s8) = G_SEXT %0(s1)
@ -314,12 +314,12 @@ body: |
liveins: $edi
; X32-LABEL: name: test_sext_i1toi16
; X32: [[DEF:%[0-9]+]]:_(s16) = G_IMPLICIT_DEF
; X32: $ax = COPY [[DEF]](s16)
; X32: [[C:%[0-9]+]]:_(s16) = G_CONSTANT i16 0
; X32: $ax = COPY [[C]](s16)
; X32: RET 0, implicit $ax
; X64-LABEL: name: test_sext_i1toi16
; X64: [[DEF:%[0-9]+]]:_(s16) = G_IMPLICIT_DEF
; X64: $ax = COPY [[DEF]](s16)
; X64: [[C:%[0-9]+]]:_(s16) = G_CONSTANT i16 0
; X64: $ax = COPY [[C]](s16)
; X64: RET 0, implicit $ax
%0(s1) = G_IMPLICIT_DEF
%1(s16) = G_SEXT %0(s1)
@ -341,12 +341,12 @@ body: |
liveins: $edi
; X32-LABEL: name: test_sext_i1
; X32: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
; X32: $eax = COPY [[DEF]](s32)
; X32: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
; X32: $eax = COPY [[C]](s32)
; X32: RET 0, implicit $eax
; X64-LABEL: name: test_sext_i1
; X64: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
; X64: $eax = COPY [[DEF]](s32)
; X64: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
; X64: $eax = COPY [[C]](s32)
; X64: RET 0, implicit $eax
%0(s1) = G_IMPLICIT_DEF
%2(s32) = G_SEXT %0(s1)

View File

@ -11,32 +11,32 @@ body: |
liveins:
; X64-LABEL: name: test_implicit_def
; X64: [[DEF:%[0-9]+]]:_(p0) = G_IMPLICIT_DEF
; X64: [[C:%[0-9]+]]:_(s8) = G_CONSTANT i8 0
; X64: G_STORE [[C]](s8), [[DEF]](p0) :: (store 1)
; X64: [[DEF1:%[0-9]+]]:_(s8) = G_IMPLICIT_DEF
; X64: G_STORE [[DEF1]](s8), [[DEF]](p0) :: (store 1)
; X64: [[DEF2:%[0-9]+]]:_(s8) = G_IMPLICIT_DEF
; X64: G_STORE [[DEF2]](s8), [[DEF]](p0) :: (store 1)
; X64: [[DEF3:%[0-9]+]]:_(s16) = G_IMPLICIT_DEF
; X64: G_STORE [[DEF3]](s16), [[DEF]](p0) :: (store 2)
; X64: [[DEF4:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
; X64: G_STORE [[DEF4]](s32), [[DEF]](p0) :: (store 4)
; X64: [[DEF5:%[0-9]+]]:_(s64) = G_IMPLICIT_DEF
; X64: G_STORE [[DEF5]](s64), [[DEF]](p0) :: (store 8)
; X64: [[DEF2:%[0-9]+]]:_(s16) = G_IMPLICIT_DEF
; X64: G_STORE [[DEF2]](s16), [[DEF]](p0) :: (store 2)
; X64: [[DEF3:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
; X64: G_STORE [[DEF3]](s32), [[DEF]](p0) :: (store 4)
; X64: [[DEF4:%[0-9]+]]:_(s64) = G_IMPLICIT_DEF
; X64: G_STORE [[DEF4]](s64), [[DEF]](p0) :: (store 8)
; X32-LABEL: name: test_implicit_def
; X32: [[DEF:%[0-9]+]]:_(p0) = G_IMPLICIT_DEF
; X32: [[C:%[0-9]+]]:_(s8) = G_CONSTANT i8 0
; X32: G_STORE [[C]](s8), [[DEF]](p0) :: (store 1)
; X32: [[DEF1:%[0-9]+]]:_(s8) = G_IMPLICIT_DEF
; X32: G_STORE [[DEF1]](s8), [[DEF]](p0) :: (store 1)
; X32: [[DEF2:%[0-9]+]]:_(s8) = G_IMPLICIT_DEF
; X32: G_STORE [[DEF2]](s8), [[DEF]](p0) :: (store 1)
; X32: [[DEF3:%[0-9]+]]:_(s16) = G_IMPLICIT_DEF
; X32: G_STORE [[DEF3]](s16), [[DEF]](p0) :: (store 2)
; X32: [[DEF2:%[0-9]+]]:_(s16) = G_IMPLICIT_DEF
; X32: G_STORE [[DEF2]](s16), [[DEF]](p0) :: (store 2)
; X32: [[DEF3:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
; X32: G_STORE [[DEF3]](s32), [[DEF]](p0) :: (store 4)
; X32: [[DEF4:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
; X32: G_STORE [[DEF4]](s32), [[DEF]](p0) :: (store 4)
; X32: [[DEF5:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
; X32: [[DEF6:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
; X32: G_STORE [[DEF5]](s32), [[DEF]](p0) :: (store 4, align 8)
; X32: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
; X32: [[GEP:%[0-9]+]]:_(p0) = G_GEP [[DEF]], [[C]](s32)
; X32: G_STORE [[DEF6]](s32), [[GEP]](p0) :: (store 4)
; X32: G_STORE [[DEF4]](s32), [[DEF]](p0) :: (store 4, align 8)
; X32: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
; X32: [[GEP:%[0-9]+]]:_(p0) = G_GEP [[DEF]], [[C1]](s32)
; X32: G_STORE [[DEF5]](s32), [[GEP]](p0) :: (store 4)
%5:_(p0) = G_IMPLICIT_DEF
%0:_(s1) = G_IMPLICIT_DEF
G_STORE %0, %5 ::(store 1)