From 65b3a9381fe2b54e893ead41d8d1975815cd1519 Mon Sep 17 00:00:00 2001 From: Max Kazantsev Date: Wed, 26 May 2021 18:35:30 +0700 Subject: [PATCH] [Test] Add Loop Deletion test with irreducible CFG MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Authored by Mikael Holmén. It demonstrated miscompile on irreducible CFG with patch "[LoopDeletion] Break backedge if we can prove that the loop is exited on 1st iteration". The patch is reverted. Checking in the test to make sure this bug does not return. --- .../LoopDeletion/irreducible-cfg.ll | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 test/Transforms/LoopDeletion/irreducible-cfg.ll diff --git a/test/Transforms/LoopDeletion/irreducible-cfg.ll b/test/Transforms/LoopDeletion/irreducible-cfg.ll new file mode 100644 index 00000000000..b0d34bb3e24 --- /dev/null +++ b/test/Transforms/LoopDeletion/irreducible-cfg.ll @@ -0,0 +1,69 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -loop-deletion -S | FileCheck %s +; RUN: opt < %s -passes='loop(loop-deletion)' -S | FileCheck %s + +; Make sure we do not get the miscompile on this test with irreducible CFG. +define i16 @test(i16 %j, i16 %k, i16 %recurs) { ; If we have %j: 1, %k: 1, %recurs: 0 +; CHECK-LABEL: @test( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i16 [[RECURS:%.*]], 0 +; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] +; CHECK: if.then: +; CHECK-NEXT: [[CALL:%.*]] = tail call i16 @test(i16 0, i16 0, i16 0) +; CHECK-NEXT: br label [[IF_END]] +; CHECK: if.end: +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[J:%.*]], 0 +; CHECK-NEXT: br label [[BB2:%.*]] +; CHECK: bb2: +; CHECK-NEXT: [[K_ADDR_0:%.*]] = phi i16 [ [[K:%.*]], [[IF_END]] ], [ [[K_ADDR_2:%.*]], [[BB12:%.*]] ] +; CHECK-NEXT: [[RESULT_0:%.*]] = phi i16 [ 0, [[IF_END]] ], [ 20, [[BB12]] ] +; CHECK-NEXT: br i1 [[CMP]], label [[BB12]], label [[BB4:%.*]] +; CHECK: bb4: +; CHECK-NEXT: [[K_ADDR_1:%.*]] = phi i16 [ [[K_ADDR_0]], [[BB2]] ], [ [[K_ADDR_2]], [[BB12]] ] +; CHECK-NEXT: [[X_1:%.*]] = phi i16 [ 0, [[BB2]] ], [ 1, [[BB12]] ] +; CHECK-NEXT: [[RESULT_1:%.*]] = phi i16 [ [[RESULT_0]], [[BB2]] ], [ 10, [[BB12]] ] +; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i16 [[K_ADDR_1]], 0 +; CHECK-NEXT: br i1 [[CMP2]], label [[BB13:%.*]], label [[BB12]] +; CHECK: bb12: +; CHECK-NEXT: [[K_ADDR_2]] = phi i16 [ [[K_ADDR_0]], [[BB2]] ], [ 0, [[BB4]] ] +; CHECK-NEXT: [[X_2:%.*]] = phi i16 [ 1, [[BB2]] ], [ [[X_1]], [[BB4]] ] +; CHECK-NEXT: [[CMP5:%.*]] = icmp eq i16 [[X_2]], 0 +; CHECK-NEXT: br i1 [[CMP5]], label [[BB2]], label [[BB4]] +; CHECK: bb13: +; CHECK-NEXT: [[RESULT_1_LCSSA:%.*]] = phi i16 [ [[RESULT_1]], [[BB4]] ] +; CHECK-NEXT: ret i16 [[RESULT_1_LCSSA]] +; +entry: + %tobool.not = icmp eq i16 %recurs, 0 ; 1 + br i1 %tobool.not, label %if.end, label %if.then ; -> if.end + +if.then: ; preds = %entry + %call = tail call i16 @test(i16 0, i16 0, i16 0) + br label %if.end + +if.end: ; preds = %if.then, %entry + %cmp = icmp eq i16 %j, 0 ; 0 + br label %bb2 ; -> bb2 + +bb2: ; preds = %bb12, %if.end + %k.addr.0 = phi i16 [ %k, %if.end ], [ %k.addr.2, %bb12 ] ; 1 + %result.0 = phi i16 [ 0, %if.end ], [ 20, %bb12 ] ; 0 + br i1 %cmp, label %bb12, label %bb4 ; %cmp: 0 -> bb4 + +bb4: ; preds = %bb12, %bb2 + %k.addr.1 = phi i16 [ %k.addr.0, %bb2 ], [ %k.addr.2, %bb12 ] ; 1 + %x.1 = phi i16 [ 0, %bb2 ], [ 1, %bb12 ] ; 0 + %result.1 = phi i16 [ %result.0, %bb2 ], [ 10, %bb12 ] + %cmp2 = icmp eq i16 %k.addr.1, 0 ; 0 + br i1 %cmp2, label %bb13, label %bb12 ; -> bb12 + +bb12: ; preds = %bb4, %bb2 + %k.addr.2 = phi i16 [ %k.addr.0, %bb2 ], [ 0, %bb4 ] ; 0 + %x.2 = phi i16 [ 1, %bb2 ], [ %x.1, %bb4 ] ; 0 + %cmp5 = icmp eq i16 %x.2, 0 ; 1 + br i1 %cmp5, label %bb2, label %bb4 ; -> bb2 + +bb13: ; preds = %bb4 + %result.1.lcssa = phi i16 [ %result.1, %bb4 ] + ret i16 %result.1.lcssa +}