[LLVMbugs] [Bug 13371] New: indvars pass incorrectly substitutes 'undef' values

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Sun Jul 15 18:41:51 PDT 2012


http://llvm.org/bugs/show_bug.cgi?id=13371

             Bug #: 13371
           Summary: indvars pass incorrectly substitutes 'undef' values
           Product: tools
           Version: 3.1
          Platform: PC
        OS/Version: Linux
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: opt
        AssignedTo: unassignedbugs at nondot.org
        ReportedBy: kmod576 at gmail.com
                CC: llvmbugs at cs.uiuc.edu
    Classification: Unclassified


I'm hesitant to submit a bug about handling of 'undef' values, but this seems
like an actual bug rather than acceptable undefined behavior.  Basically, when
indvars tries to canonicalize the loop variable, it can select an induction
variable that is undef; typically this means that the loop will execute
0/1/infinite number of times.  In this example (which prints 1 through 100),
doing some simple arithmetic with an undef variable produces an infinite loop
once optimized:

@.str3 = private constant [6 x i8] c"%lld\0A\00", align 1
declare i32 @printf(i8* noalias nocapture, ...) nounwind
define i64 @main() nounwind {
func_start:
  br label %block9
block9:                                           ; preds = %block9,
%func_start
  %undef = phi i64 [ %next_undef, %block9 ], [ undef, %func_start ]
  %iter = phi i64 [ %next_iter, %block9 ], [ 0, %func_start ]
  %next_iter = add nsw i64 %iter, 1
  %0 = tail call i32 (i8*, ...)* @printf(i8* noalias nocapture getelementptr
inbounds ([6 x i8]* @.str3, i64 0, i64 0), i64 %next_iter, i64 %undef)
  %next_undef = add nsw i64 %undef, 1
  %_tmp_3 = icmp slt i64 %next_iter, 100
  br i1 %_tmp_3, label %block9, label %exit
exit:                                             ; preds = %block9
  ret i64 0
}

which gets optimized (using "opt -indvars test.ll -S") to the following, which
on my setup counts up from 1 and doesn't stop:


@.str3 = private constant [6 x i8] c"%lld\0A\00", align 1
declare i32 @printf(i8* noalias nocapture, ...) nounwind
define i64 @main() nounwind {
func_start:
  br label %block9
block9:                                           ; preds = %block9,
%func_start
  %undef = phi i64 [ %next_undef, %block9 ], [ undef, %func_start ]
  %iter = phi i64 [ %next_iter, %block9 ], [ 0, %func_start ]
  %next_iter = add nsw i64 %iter, 1
  %0 = tail call i32 (i8*, ...)* @printf(i8* noalias nocapture getelementptr
inbounds ([6 x i8]* @.str3, i64 0, i64 0), i64 %next_iter, i64 %undef)
  %next_undef = add nsw i64 %undef, 1
  %exitcond = icmp ne i64 %next_undef, undef ; <<<< notice
  br i1 %exitcond, label %block9, label %exit
exit:                                             ; preds = %block9
  ret i64 0
}


(notice the exit condition that compares against undef)

I have a simple patch that appears to correct this behavior: in
lib/Transforms/Scalar/IndVarSimplify.cpp::LinearFunctionTestReplace, add this
test at line 1491:

  if (isa<UndefValue>(ExitCnt))
      return NULL;

I don't claim that this is the best way to solve this problem (it breaks out of
the optimization at an unexpected place, and there's probably still the ability
to find a different loop induction variable), but given that this is so rare an
issue that no one has noticed it, I personally would think that this is
acceptable.

-- 
Configure bugmail: http://llvm.org/bugs/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.



More information about the llvm-bugs mailing list