Test source: git
Source: <stdin> ---------------------------------------- define void @For_PositiveStride(* nocapture %ar, i64 %n, i64 %m) { %entry: %0 = shl nuw i64 %m, 2 br label %for.cond1.preheader %for.cond1.preheader: %i.017 = phi i64 [ 0, %entry ], [ %inc5, %for.inc4 ] %1 = mul i64 %m, %i.017 %scevgep = gep * nocapture %ar, 4 x i64 %1 %scevgep1 = bitcast * %scevgep to * %mul = mul nsw i64 %i.017, %m memset * %scevgep1 align 4, i8 0, i64 %0 br label %for.inc4 %for.inc4: %inc5 = add nsw nuw i64 %i.017, 1 %exitcond18.not = icmp eq i64 %inc5, %n br i1 %exitcond18.not, label %for.end6, label %for.cond1.preheader %for.end6: ret void } => define void @For_PositiveStride(* nocapture %ar, i64 %n, i64 %m) { %entry: %ar1 = bitcast * nocapture %ar to * %0 = shl nuw i64 %m, 2 %1 = mul i64 %m, %n %2 = shl i64 %1, 2 memset * %ar1 align 4, i8 0, i64 %2 ret void } Transformation seems to be correct! ---------------------------------------- define void @For_NegativeStride(* %ar, i32 %n, i32 %m) { %entry: %sub = sub nsw i32 %n, 1 %conv = sext i32 %sub to i64 %cmp1 = icmp sge i64 %conv, 0 br i1 %cmp1, label %for.body.lr.ph, label %for.end %for.body.lr.ph: %conv1 = sext i32 %m to i64 %conv2 = sext i32 %m to i64 %mul3 = mul i64 %conv2, 4 br label %for.body %for.body: %i.02 = phi i64 [ %conv, %for.body.lr.ph ], [ %dec, %for.inc ] %mul = mul nsw i64 %i.02, %conv1 %add.ptr = gep inbounds * %ar, 4 x i64 %mul %0 = bitcast * %add.ptr to * memset * %0 align 4, i8 0, i64 %mul3 br label %for.inc %for.inc: %dec = add nsw i64 %i.02, -1 %cmp = icmp sge i64 %dec, 0 br i1 %cmp, label %for.body, label %for.cond.for.end_crit_edge %for.cond.for.end_crit_edge: br label %for.end %for.end: ret void } => define void @For_NegativeStride(* %ar, i32 %n, i32 %m) { %entry: %ar1 = bitcast * %ar to * %sub = sub nsw i32 %n, 1 %conv = sext i32 %sub to i64 %cmp1 = icmp sge i64 %conv, 0 br i1 %cmp1, label %for.body.lr.ph, label %for.end %for.body.lr.ph: %conv1 = sext i32 %m to i64 %conv2 = sext i32 %m to i64 %mul3 = mul i64 %conv2, 4 %0 = sub i64 %conv, -1 %1 = mul i64 %conv1, %0 %2 = shl i64 %1, 2 memset * %ar1 align 4, i8 0, i64 %2 br label %for.end %for.end: ret void } Transformation doesn't verify! ERROR: Source is more defined than target Example: * %ar = poison i32 %n = #x00000001 (1) i32 %m = #x00000000 (0) Source: i32 %sub = #x00000000 (0) i64 %conv = #x0000000000000000 (0) i1 %cmp1 = #x1 (1) >> Jump to %for.body.lr.ph i64 %conv1 = #x0000000000000000 (0) i64 %conv2 = #x0000000000000000 (0) i64 %mul3 = #x0000000000000000 (0) >> Jump to %for.body i64 %i.02 = #x0000000000000000 (0) i64 %mul = #x0000000000000000 (0) * %add.ptr = poison * %0 = poison >> Jump to %for.inc i64 %dec = #xffffffffffffffff (18446744073709551615, -1) i1 %cmp = #x0 (0) >> Jump to %for.cond.for.end_crit_edge >> Jump to %for.end SOURCE MEMORY STATE =================== NON-LOCAL BLOCKS: Block 0 > size: 0 align: 1 alloc type: 0 Block 1 > align: 131072 alloc type: 0 Target: * %ar1 = poison i32 %sub = #x00000000 (0) i64 %conv = #x0000000000000000 (0) i1 %cmp1 = #x1 (1) >> Jump to %for.body.lr.ph i64 %conv1 = #x0000000000000000 (0) i64 %conv2 = #x0000000000000000 (0) i64 %mul3 = #x0000000000000000 (0) i64 %0 = #x0000000000000001 (1) i64 %1 = #x0000000000000000 (0) i64 %2 = #x0000000000000000 (0) void = UB triggered! ------------------- SMT STATS ------------------- Num queries: 7 Num invalid: 0 Num skips: 0 Num trivial: 25 (78.1%) Num timeout: 0 (0.0%) Num errors: 0 (0.0%) Num SAT: 5 (71.4%) Num UNSAT: 2 (28.6%) Alive2: Transform doesn't verify; aborting!
+ : 'RUN: at line 2' + /home/nlopes/alive2/build/opt-alive.sh '-passes=function(loop(loop-idiom,loop-deletion),simplifycfg)' -S + /home/nlopes/llvm/build/bin/FileCheck /home/nlopes/llvm/llvm/test/Transforms/LoopIdiom/memset-runtime.ll FileCheck error: '<stdin>' is empty. FileCheck command line: /home/nlopes/llvm/build/bin/FileCheck /home/nlopes/llvm/llvm/test/Transforms/LoopIdiom/memset-runtime.ll
NOTE: This test would pass if undef didn't exist!