From d31582e52feb327944e9dc0f7cb085cf645193d0 Mon Sep 17 00:00:00 2001 From: Roman Lebedev Date: Sat, 12 Oct 2019 15:35:16 +0000 Subject: [PATCH] [NFC][LoopIdiom] Add bcmp loop idiom miscompile test from PR43206. The transform forgot to check SCEV loop scopes. https://bugs.llvm.org/show_bug.cgi?id=43206 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@374661 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../LoopIdiom/bcmp-negative-tests.ll | 57 ++++++++++++++++++- 1 file changed, 54 insertions(+), 3 deletions(-) diff --git a/test/Transforms/LoopIdiom/bcmp-negative-tests.ll b/test/Transforms/LoopIdiom/bcmp-negative-tests.ll index 9d770adf979..a4d4a3d250a 100644 --- a/test/Transforms/LoopIdiom/bcmp-negative-tests.ll +++ b/test/Transforms/LoopIdiom/bcmp-negative-tests.ll @@ -1,9 +1,7 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt -loop-idiom < %s -S | FileCheck %s +; RUN: opt -loop-idiom -verify -verify-each -verify-dom-info -verify-loop-info < %s -S | FileCheck %s --implicit-check-not=bcmp --implicit-check-not=memcmp ; CHECK: source_filename -; CHECK-NOT; bcmp -; CHECK-NOT; memcmp target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" @@ -478,3 +476,56 @@ cleanup: %res = phi i1 [ false, %for.body ], [ true, %for.inc ] ret i1 %res } + +; See https://bugs.llvm.org/show_bug.cgi?id=43206 for original reduced (but runnable) test: +; +; bool do_check(int i_max, int j_max, int**bptr, int* fillch) { +; for (int i = 0; i < i_max; i++) +; for (int j = 0; j < j_max; j++) +; if (bptr[i][j] != fillch[i]) +; return 1; +; return 0; +; } +; The loads proceed differently here - fillch[i] changes once per outer loop, +; while bptr[i][j] changes both in inner loop, and in outer loop. +define i1 @pr43206_different_loops(i32 %i_max, i32 %j_max, i32** %bptr, i32* %fillch) { +entry: + %cmp31 = icmp sgt i32 %i_max, 0 + %cmp229 = icmp sgt i32 %j_max, 0 + %or.cond = and i1 %cmp31, %cmp229 + br i1 %or.cond, label %for.cond1.preheader.us.preheader, label %cleanup12 + +for.cond1.preheader.us.preheader: ; preds = %entry + %wide.trip.count38 = zext i32 %i_max to i64 + %wide.trip.count = zext i32 %j_max to i64 + br label %for.cond1.preheader.us + +for.cond1.preheader.us: ; preds = %for.cond1.for.inc10_crit_edge.us, %for.cond1.preheader.us.preheader + %indvars.iv36 = phi i64 [ 0, %for.cond1.preheader.us.preheader ], [ %indvars.iv.next37, %for.cond1.for.inc10_crit_edge.us ] + %arrayidx.us = getelementptr inbounds i32*, i32** %bptr, i64 %indvars.iv36 + %v0 = load i32*, i32** %arrayidx.us, align 8 + %arrayidx8.us = getelementptr inbounds i32, i32* %fillch, i64 %indvars.iv36 + %v1 = load i32, i32* %arrayidx8.us, align 4 + br label %for.body4.us + +for.cond1.us: ; preds = %for.body4.us + %exitcond = icmp eq i64 %indvars.iv.next, %wide.trip.count + br i1 %exitcond, label %for.cond1.for.inc10_crit_edge.us, label %for.body4.us + +for.body4.us: ; preds = %for.cond1.us, %for.cond1.preheader.us + %indvars.iv = phi i64 [ 0, %for.cond1.preheader.us ], [ %indvars.iv.next, %for.cond1.us ] + %arrayidx6.us = getelementptr inbounds i32, i32* %v0, i64 %indvars.iv + %v2 = load i32, i32* %arrayidx6.us, align 4 + %cmp9.us = icmp eq i32 %v2, %v1 + %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 + br i1 %cmp9.us, label %for.cond1.us, label %cleanup12 + +for.cond1.for.inc10_crit_edge.us: ; preds = %for.cond1.us + %indvars.iv.next37 = add nuw nsw i64 %indvars.iv36, 1 + %exitcond39 = icmp eq i64 %indvars.iv.next37, %wide.trip.count38 + br i1 %exitcond39, label %cleanup12, label %for.cond1.preheader.us + +cleanup12: ; preds = %for.cond1.for.inc10_crit_edge.us, %for.body4.us, %entry + %v3 = phi i1 [ false, %entry ], [ true, %for.body4.us ], [ false, %for.cond1.for.inc10_crit_edge.us ] + ret i1 %v3 +} -- 2.40.0