diff options
-rw-r--r-- | llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp | 10 | ||||
-rw-r--r-- | llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-extending-loads-cornercases.mir | 111 |
2 files changed, 119 insertions, 2 deletions
diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp index 98114d295a1..30e0da319e8 100644 --- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp +++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp @@ -154,12 +154,18 @@ bool CombinerHelper::tryCombineExtendingLoads(MachineInstr &MI) { assert(Preferred.Ty != LoadValueTy && "Extending to same type?"); // Rewrite the load and schedule the canonical use for erasure. - const auto TruncateUse = [](MachineIRBuilder &Builder, MachineOperand &UseMO, - unsigned DstReg, unsigned SrcReg) { + const auto TruncateUse = [&MI](MachineIRBuilder &Builder, + MachineOperand &UseMO, unsigned DstReg, + unsigned SrcReg) { MachineInstr &UseMI = *UseMO.getParent(); MachineBasicBlock &UseMBB = *UseMI.getParent(); Builder.setInsertPt(UseMBB, MachineBasicBlock::iterator(UseMI)); + + if (UseMI.isPHI()) + Builder.setInsertPt(*MI.getParent(), + std::next(MachineBasicBlock::iterator(MI))); + Builder.buildTrunc(DstReg, SrcReg); }; diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-extending-loads-cornercases.mir b/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-extending-loads-cornercases.mir new file mode 100644 index 00000000000..7b9243492f5 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-extending-loads-cornercases.mir @@ -0,0 +1,111 @@ +# RUN: llc -O0 -run-pass=aarch64-prelegalizer-combiner -global-isel %s -o - | FileCheck %s + +--- | + target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" + target triple = "aarch64--" + define void @multiple_copies(i8* %addr) { + entry: + br i1 0, label %if, label %else + if: + br label %exit + else: + br label %exit + exit: + ret void + } + + define void @sink_to_phi(i8* %addr) { + entry: + br i1 0, label %if, label %exit + if: + br label %exit + exit: + ret void + } +... + +--- +name: multiple_copies +# CHECK-LABEL: name: multiple_copies +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x0, $w1 + successors: %bb.1(0x40000000), %bb.2(0x40000000); %bb.1(50.00%), %bb.2(50.00%) + ; CHECK: [[T0:%[0-9]+]]:_(s32) = G_SEXTLOAD + %0:_(p0) = COPY $x0 + %1:_(s32) = COPY $w1 + %2:_(s8) = G_LOAD %0 :: (load 1 from %ir.addr) + %3:_(s32) = G_SEXT %2 + %4:_(s32) = G_CONSTANT i32 1 + %5:_(s1) = G_ICMP intpred(ne), %1:_(s32), %4:_ + G_BRCOND %5:_(s1), %bb.1 + G_BR %bb.2.else + bb.1.if: + ; CHECK: bb.1.if: + successors: %bb.3(0x80000000) + %10:_(s8) = G_CONSTANT i8 1 + ; CHECK: [[T1:%[0-9]+]]:_(s8) = G_TRUNC [[T0]](s32) + %6:_(s8) = G_ADD %2, %10 + ; CHECK: [[T2:%[0-9]+]]:_(s8) = G_ADD [[T1]], {{.*}} + G_BR %bb.3.exit + bb.2.else: + ; CHECK: bb.2.else: + successors: %bb.3(0x80000000) + %11:_(s8) = G_CONSTANT i8 1 + ; CHECK: [[T3:%[0-9]+]]:_(s8) = G_TRUNC [[T0]](s32) + %7:_(s8) = G_SUB %2, %11 + ; CHECK: [[T4:%[0-9]+]]:_(s8) = G_SUB [[T3]], {{.*}} + G_BR %bb.3.exit + bb.3.exit: + ; CHECK: bb.3.exit: + %8:_(s8) = G_PHI %6:_(s8), %bb.1, %7:_(s8), %bb.2 + ; CHECK: [[T5:%[0-9]+]]:_(s8) = G_PHI [[T2]](s8), %bb.1, [[T4]](s8) + %9:_(s32) = G_ZEXT %8 + ; CHECK: [[T6:%[0-9]+]]:_(s32) = G_ZEXT [[T5]](s8) + ; CHECK: $w0 = COPY [[T0]](s32) + ; CHECK: $w1 = COPY [[T6]](s32) + $w0 = COPY %3 + $w1 = COPY %9 +... + +--- +name: sink_to_phi +# CHECK-LABEL: name: sink_to_phi +# This test currently tests that we don't sink if we would sink to a phi. This +# is needed to avoid inserting into the middle of the leading G_PHI instructions +# of a BB +tracksRegLiveness: true +body: | + bb.0.entry: + liveins: $x0, $w1 + successors: %bb.1(0x40000000), %bb.2(0x40000000); %bb.1(50.00%), %bb.2(50.00%) + ; CHECK: [[T0:%[0-9]+]]:_(s32) = G_SEXTLOAD + %0:_(p0) = COPY $x0 + %1:_(s32) = COPY $w1 + %2:_(s8) = G_LOAD %0 :: (load 1 from %ir.addr) + ; CHECK: [[T4:%[0-9]+]]:_(s8) = G_TRUNC [[T0]](s32) + %3:_(s32) = G_SEXT %2 + %4:_(s32) = G_CONSTANT i32 1 + %5:_(s1) = G_ICMP intpred(ne), %1:_(s32), %4:_ + G_BRCOND %5:_(s1), %bb.1 + G_BR %bb.2.exit + bb.1.if: + ; CHECK: bb.1.if: + successors: %bb.2(0x80000000) + %10:_(s8) = G_CONSTANT i8 1 + ; CHECK: [[T1:%[0-9]+]]:_(s8) = G_TRUNC [[T0]](s32) + %6:_(s8) = G_ADD %2, %10 + ; CHECK: [[T2:%[0-9]+]]:_(s8) = G_ADD [[T1]], {{.*}} + G_BR %bb.2.exit + bb.2.exit: + ; CHECK: bb.2.exit: + %8:_(s8) = G_PHI %6:_(s8), %bb.1, %2:_(s8), %bb.0 + ; CHECK: [[T5:%[0-9]+]]:_(s8) = G_PHI [[T2]](s8), %bb.1, [[T4]](s8) + %9:_(s32) = G_ZEXT %8 + ; CHECK: [[T6:%[0-9]+]]:_(s32) = G_ZEXT [[T5]](s8) + ; CHECK: $w0 = COPY [[T0]](s32) + ; CHECK: $w1 = COPY [[T6]](s32) + $w0 = COPY %3 + $w1 = COPY %9 +... |