summaryrefslogtreecommitdiffstats
path: root/llvm/test/Transforms/IRCE/range_intersect_miscompile.ll
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/test/Transforms/IRCE/range_intersect_miscompile.ll')
-rw-r--r--llvm/test/Transforms/IRCE/range_intersect_miscompile.ll45
1 files changed, 45 insertions, 0 deletions
diff --git a/llvm/test/Transforms/IRCE/range_intersect_miscompile.ll b/llvm/test/Transforms/IRCE/range_intersect_miscompile.ll
new file mode 100644
index 00000000000..3a93ad1f396
--- /dev/null
+++ b/llvm/test/Transforms/IRCE/range_intersect_miscompile.ll
@@ -0,0 +1,45 @@
+; RUN: opt -irce -S < %s 2>&1 | FileCheck %s
+
+; This test demonstrates a miscompile: the outer loop's IV iterates in range of
+; [2, 400) and the range check is done against value 331. Due to a bug in range
+; intersection IRCE manages to eliminate the range check without inserting a
+; postloop, which is incorrect. So far IRCE is prohibited for this case.
+
+define void @test_01() {
+
+; CHECK-LABEL: test_01
+; CHECK-NOT: br i1 true
+
+entry:
+ br label %loop_header
+
+loop_header: ; preds = %loop_latch, %entry
+ %iv = phi i32 [ 2, %entry ], [ %iv_next, %loop_latch ]
+ %iv.prev = phi i32 [ 1, %entry ], [ %iv, %loop_latch ]
+ %tmp2 = icmp sgt i32 %iv.prev, -1
+ br i1 %tmp2, label %loop_header.split.us, label %exit
+
+loop_header.split.us: ; preds = %loop_header
+ br label %inner_loop
+
+inner_loop: ; preds = %inner_loop, %loop_header.split.us
+ %inner_iv = phi i32 [ 1, %loop_header.split.us ], [ %inner_iv_next, %inner_loop ]
+ %inner_iv_next = add nuw nsw i32 %inner_iv, 1
+ %inner_cond = icmp ult i32 %inner_iv_next, 31
+ br i1 %inner_cond, label %inner_loop, label %range_check_block
+
+exit: ; preds = %loop_latch, %loop_header
+ ret void
+
+range_check_block: ; preds = %inner_loop
+ %range_check = icmp slt i32 %iv, 331
+ br i1 %range_check, label %loop_latch, label %deopt
+
+loop_latch: ; preds = %range_check_block
+ %iv_next = add i32 %iv, 1
+ %loop_cond = icmp ult i32 %iv_next, 400
+ br i1 %loop_cond, label %loop_header, label %exit
+
+deopt: ; preds = %range_check_block
+ ret void
+}
OpenPOWER on IntegriCloud