From 53abe3ff66a54117308352d379837c7d3229f8d6 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 4 Mar 2022 11:13:40 +0100 Subject: [PATCH] [MergeICmp] Make instruction move robust against empty block (NFCI) Use the overload that support moving into an empty block. I don't think that this situation can occur right now, but it can happen with the change from e7fb1c15cb85d748c1c4fdd5a2eb5613ec7bef1d, and the test is derived from the issue reported there. --- llvm/lib/Transforms/Scalar/MergeICmps.cpp | 5 +-- .../Transforms/MergeICmps/X86/no-gep-other-work.ll | 48 ++++++++++++++++++++++ 2 files changed, 50 insertions(+), 3 deletions(-) create mode 100644 llvm/test/Transforms/MergeICmps/X86/no-gep-other-work.ll diff --git a/llvm/lib/Transforms/Scalar/MergeICmps.cpp b/llvm/lib/Transforms/Scalar/MergeICmps.cpp index d38e362..1c1026b 100644 --- a/llvm/lib/Transforms/Scalar/MergeICmps.cpp +++ b/llvm/lib/Transforms/Scalar/MergeICmps.cpp @@ -270,9 +270,8 @@ void BCECmpBlock::split(BasicBlock *NewParent, AliasAnalysis &AA) const { } // Do the actual spliting. - for (Instruction *Inst : reverse(OtherInsts)) { - Inst->moveBefore(&*NewParent->begin()); - } + for (Instruction *Inst : reverse(OtherInsts)) + Inst->moveBefore(*NewParent, NewParent->begin()); } bool BCECmpBlock::canSplit(AliasAnalysis &AA) const { diff --git a/llvm/test/Transforms/MergeICmps/X86/no-gep-other-work.ll b/llvm/test/Transforms/MergeICmps/X86/no-gep-other-work.ll new file mode 100644 index 0000000..3ffbd93 --- /dev/null +++ b/llvm/test/Transforms/MergeICmps/X86/no-gep-other-work.ll @@ -0,0 +1,48 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -S -mergeicmps < %s | FileCheck %s + +; This does not use a GEP for the zero-offset comparison and requires a +; split for other work. + +target triple = "x86_64-grtev4-linux-gnu" + +declare void @other_work() + +define i1 @test(i8* dereferenceable(2) %arg, i8* dereferenceable(2) %arg1) { +; CHECK-LABEL: @test( +; CHECK-NEXT: entry: +; CHECK-NEXT: call void @other_work() +; CHECK-NEXT: [[ARG_OFF:%.*]] = getelementptr inbounds i8, i8* [[ARG:%.*]], i64 1 +; CHECK-NEXT: [[ARG1_OFF:%.*]] = getelementptr inbounds i8, i8* [[ARG1:%.*]], i64 1 +; CHECK-NEXT: [[ARG_OFF_VAL:%.*]] = load i8, i8* [[ARG_OFF]], align 1 +; CHECK-NEXT: [[ARG1_OFF_VAL:%.*]] = load i8, i8* [[ARG1_OFF]], align 1 +; CHECK-NEXT: [[CMP_OFF:%.*]] = icmp eq i8 [[ARG_OFF_VAL]], [[ARG1_OFF_VAL]] +; CHECK-NEXT: br i1 [[CMP_OFF]], label [[IF:%.*]], label [[JOIN:%.*]] +; CHECK: if: +; CHECK-NEXT: [[ARG_VAL:%.*]] = load i8, i8* [[ARG]], align 1 +; CHECK-NEXT: [[ARG1_VAL:%.*]] = load i8, i8* [[ARG1]], align 1 +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[ARG_VAL]], [[ARG1_VAL]] +; CHECK-NEXT: br label [[JOIN]] +; CHECK: join: +; CHECK-NEXT: [[PHI:%.*]] = phi i1 [ false, [[ENTRY:%.*]] ], [ [[CMP]], [[IF]] ] +; CHECK-NEXT: ret i1 [[PHI]] +; +entry: + call void @other_work() + %arg.off = getelementptr inbounds i8, i8* %arg, i64 1 + %arg1.off = getelementptr inbounds i8, i8* %arg1, i64 1 + %arg.off.val = load i8, i8* %arg.off + %arg1.off.val = load i8, i8* %arg1.off + %cmp.off = icmp eq i8 %arg.off.val, %arg1.off.val + br i1 %cmp.off, label %if, label %join + +if: + %arg.val = load i8, i8* %arg + %arg1.val = load i8, i8* %arg1 + %cmp = icmp eq i8 %arg.val, %arg1.val + br label %join + +join: + %phi = phi i1 [ false, %entry ], [ %cmp, %if ] + ret i1 %phi +} -- 2.7.4