Index: include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h =================================================================== --- include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h +++ include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h @@ -51,6 +51,18 @@ markInstAndDefDead(MI, *MRI.getVRegDef(SrcReg), DeadInsts); return true; } + + // aext([asz]ext x) -> [asz]ext x + unsigned ExtSrc; + MachineInstr *ExtMI; + if (mi_match(SrcReg, MRI, + m_all_of(m_MInstr(ExtMI), m_any_of(m_GAnyExt(m_Reg(ExtSrc)), + m_GSExt(m_Reg(ExtSrc)), + m_GZExt(m_Reg(ExtSrc)))))) { + Builder.buildInstr(ExtMI->getOpcode(), DstReg, ExtSrc); + markInstAndDefDead(MI, *ExtMI, DeadInsts); + return true; + } return tryFoldImplicitDef(MI, DeadInsts); } Index: test/CodeGen/AArch64/GlobalISel/legalize-ext.mir =================================================================== --- test/CodeGen/AArch64/GlobalISel/legalize-ext.mir +++ test/CodeGen/AArch64/GlobalISel/legalize-ext.mir @@ -51,10 +51,8 @@ ; 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 [[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: [[AND3:%[0-9]+]]:_(s32) = G_AND [[TRUNC10]], [[C6]] + ; CHECK: $w0 = COPY [[AND3]](s32) ; CHECK: [[TRUNC11:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64) ; CHECK: $w0 = COPY [[TRUNC11]](s32) ; CHECK: [[TRUNC12:%[0-9]+]]:_(s32) = G_TRUNC [[COPY]](s64) @@ -118,3 +116,59 @@ $w0 = COPY %27(s32) ... +--- +name: test_anyext_anyext +body: | + bb.0: + liveins: $w0 + + ; CHECK-LABEL: name: test_anyext_anyext + ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0 + ; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY [[COPY]](s32) + ; CHECK: $w0 = COPY [[COPY1]](s32) + %0:_(s32) = COPY $w0 + %1:_(s1) = G_TRUNC %0(s32) + %2:_(s8) = G_ANYEXT %1(s1) + %3:_(s32) = G_ANYEXT %2(s8) + $w0 = COPY %3(s32) + +... +--- +name: test_anyext_sext +body: | + bb.0: + liveins: $w0 + + ; CHECK-LABEL: name: test_anyext_sext + ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0 + ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 31 + ; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY [[COPY]](s32) + ; CHECK: [[SHL:%[0-9]+]]:_(s32) = G_SHL [[COPY1]], [[C]] + ; CHECK: [[ASHR:%[0-9]+]]:_(s32) = G_ASHR [[SHL]], [[C]] + ; CHECK: $w0 = COPY [[ASHR]](s32) + %0:_(s32) = COPY $w0 + %1:_(s1) = G_TRUNC %0(s32) + %2:_(s8) = G_SEXT %1(s1) + %3:_(s32) = G_ANYEXT %2(s8) + $w0 = COPY %3(s32) + +... +--- +name: test_anyext_zext +body: | + bb.0: + liveins: $w0 + + ; CHECK-LABEL: name: test_anyext_zext + ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0 + ; CHECK: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1 + ; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY [[COPY]](s32) + ; CHECK: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY1]], [[C]] + ; CHECK: $w0 = COPY [[AND]](s32) + %0:_(s32) = COPY $w0 + %1:_(s1) = G_TRUNC %0(s32) + %2:_(s8) = G_ZEXT %1(s1) + %3:_(s32) = G_ANYEXT %2(s8) + $w0 = COPY %3(s32) + +...