Michael Kruse via llvm-dev
2021-Feb-18 00:35 UTC
[llvm-dev] Potentially unsafe loop optimization
Executing the add instruction that results in an unsigned wrap despite the nuw flag is not an undefined instruction, but results in a 'poison' value. Only certain uses of a poison value results in undefined behaviour. See https://llvm.org/docs/LangRef.html#poison-values for more information. Am Mi., 17. Feb. 2021 um 17:58 Uhr schrieb Richard Kenner via llvm-dev <llvm-dev at lists.llvm.org>:> The loop end test looks like:> > loop.cond.iter: ; preds = %8 > %6 = load i8, i8* %c, align 1, !tbaa !5 > %loop.iter.cond = icmp eq i8 %6, -1 > br i1 %loop.iter.cond, label %loop.exit, label %loop.iter > > loop.iter: ; preds = %loop.cond.iter > %next.loop.var = add nuw i8 %6, 1 > store i8 %next.loop.var, i8* %c, align 1, !tbaa !5 > br label %loop.cond > > This looks correct. We do the add after the conditional branch, so > we'll never see it overflow.I think this loop already has undefined behaviour. If %6 eventually loads the value 255, %next.loop.var will be poison. Storing poison to memory is not itself undefined, but write an undefined value. Michael
Richard Kenner via llvm-dev
2021-Feb-18 00:39 UTC
[llvm-dev] Potentially unsafe loop optimization
> Executing the add instruction that results in an unsigned wrap despite > the nuw flag is not an undefined instruction, but results in a > 'poison' value. Only certain uses of a poison value results in > undefined behaviour. See > https://llvm.org/docs/LangRef.html#poison-values for more information.I stand corrected. But then why does the code generator view the branch as always true?> > loop.cond.iter: ; preds = %8 > > %6 = load i8, i8* %c, align 1, !tbaa !5 > > %loop.iter.cond = icmp eq i8 %6, -1 > > br i1 %loop.iter.cond, label %loop.exit, label %loop.iter > > > > loop.iter: ; preds = %loop.cond.iter > > %next.loop.var = add nuw i8 %6, 1 > > store i8 %next.loop.var, i8* %c, align 1, !tbaa !5 > > br label %loop.cond > > > > This looks correct. We do the add after the conditional branch, so > > we'll never see it overflow. > > I think this loop already has undefined behaviour. If %6 eventually > loads the value 255, %next.loop.var will be poison.I don't think so because if %6 is loaded with the value 255 (-1), the branch won't go to loop.iter where the add is done. So we never get to the add that generates poison. Also, note that I tried this without the "nuw" on the original add and the optimizer put that on the add instruction that it made.