[llvm] r219462 - SimplifyCFG: Don't convert phis into selects if we could remove undef behavior
Arnold Schwaighofer
aschwaighofer at apple.com
Fri Oct 10 12:05:56 PDT 2014
Right, however the code is already there and also handles the more general:
define void @test6(i1 %cond, i8* %ptr) {
entry:
br i1 %cond, label %bb1, label %bb2
bb1:
call void foobar()
br label %bb2
bb2:
%ptr.2 = phi i8* [ %ptr, %entry ], [ null, %bb1 ]
store i8 2, i8* %ptr.2, align 8
ret void
}
=>
define void @test6(i1 %cond, i8* %ptr) {
entry:
br i1 %cond, label %bb1, label %bb2
bb1:
call void foobar()
unreachable
bb2:
store i8 2, i8* %ptr, align 8
ret void
}
There is an argument to be made to do both I guess ...
> On Oct 10, 2014, at 11:53 AM, Philip Reames <listmail at philipreames.com> wrote:
>
> Why is this pattern any worse for recognizing undefined behaviour?
>
> define void @test6(i1 %cond, i8* %ptr) {
> %ptr.2 = select i1 %cond, i8* null, i8* %ptr
> store i8 2, i8* %ptr.2, align 8
> ret void
> }
>
> We can infer that %cond can't be true, or undefined behaviour would result. This might not be implemented currently, but it certainly seems easy to do.
>
> That transformation would seem to get us the same result:
>
> define void @test6(i1 %cond, i8* %ptr) {
> store i8 2, i8* %ptr.2, align 8
> ret void
> }
>
> Philip
>
> On 10/09/2014 06:27 PM, Arnold Schwaighofer wrote:
>> Author: arnolds
>> Date: Thu Oct 9 20:27:02 2014
>> New Revision: 219462
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=219462&view=rev
>> Log:
>> SimplifyCFG: Don't convert phis into selects if we could remove undef behavior
>> instead
>>
>> We used to transform this:
>>
>> define void @test6(i1 %cond, i8* %ptr) {
>> entry:
>> br i1 %cond, label %bb1, label %bb2
>>
>> bb1:
>> br label %bb2
>>
>> bb2:
>> %ptr.2 = phi i8* [ %ptr, %entry ], [ null, %bb1 ]
>> store i8 2, i8* %ptr.2, align 8
>> ret void
>> }
>>
>> into this:
>>
>> define void @test6(i1 %cond, i8* %ptr) {
>> %ptr.2 = select i1 %cond, i8* null, i8* %ptr
>> store i8 2, i8* %ptr.2, align 8
>> ret void
>> }
>>
>> because the simplifycfg transformation into selects would happen to happen
>> before the simplifycfg transformation that removes unreachable control flow
>> (We have 'unreachable control flow' due to the store to null which is undefined
>> behavior).
>>
>> The existing transformation that removes unreachable control flow in simplifycfg
>> is:
>>
>> /// If BB has an incoming value that will always trigger undefined behavior
>> /// (eg. null pointer dereference), remove the branch leading here.
>> static bool removeUndefIntroducingPredecessor(BasicBlock *BB)
>>
>> Now we generate:
>>
>> define void @test6(i1 %cond, i8* %ptr) {
>> store i8 2, i8* %ptr.2, align 8
>> ret void
>> }
>>
>> I did not see any impact on the test-suite + externals.
>>
>> rdar://18596215
>>
>> Modified:
>> llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp
>> llvm/trunk/test/Transforms/SimplifyCFG/UnreachableEliminate.ll
>>
>> Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp?rev=219462&r1=219461&r2=219462&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp (original)
>> +++ llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Thu Oct 9 20:27:02 2014
>> @@ -1010,6 +1010,8 @@ static bool isSafeToHoistInvoke(BasicBlo
>> return true;
>> }
>> +static bool passingValueIsAlwaysUndefined(Value *V, Instruction *I);
>> +
>> /// HoistThenElseCodeToIf - Given a conditional branch that goes to BB1 and
>> /// BB2, hoist any common code in the two blocks up into the branch block. The
>> /// caller of this function guarantees that BI's block dominates BB1 and BB2.
>> @@ -1094,6 +1096,12 @@ HoistTerminator:
>> if (BB1V == BB2V)
>> continue;
>> + // Check for passingValueIsAlwaysUndefined here because we would rather
>> + // eliminate undefined control flow then converting it to a select.
>> + if (passingValueIsAlwaysUndefined(BB1V, PN) ||
>> + passingValueIsAlwaysUndefined(BB2V, PN))
>> + return Changed;
>> +
>> if (isa<ConstantExpr>(BB1V) && !isSafeToSpeculativelyExecute(BB1V, DL))
>> return Changed;
>> if (isa<ConstantExpr>(BB2V) && !isSafeToSpeculativelyExecute(BB2V, DL))
>> @@ -1508,6 +1516,11 @@ static bool SpeculativelyExecuteBB(Branc
>> if (ThenV == OrigV)
>> continue;
>> + // Don't convert to selects if we could remove undefined behavior instead.
>> + if (passingValueIsAlwaysUndefined(OrigV, PN) ||
>> + passingValueIsAlwaysUndefined(ThenV, PN))
>> + return false;
>> +
>> HaveRewritablePHIs = true;
>> ConstantExpr *OrigCE = dyn_cast<ConstantExpr>(OrigV);
>> ConstantExpr *ThenCE = dyn_cast<ConstantExpr>(ThenV);
>>
>> Modified: llvm/trunk/test/Transforms/SimplifyCFG/UnreachableEliminate.ll
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyCFG/UnreachableEliminate.ll?rev=219462&r1=219461&r2=219462&view=diff
>> ==============================================================================
>> --- llvm/trunk/test/Transforms/SimplifyCFG/UnreachableEliminate.ll (original)
>> +++ llvm/trunk/test/Transforms/SimplifyCFG/UnreachableEliminate.ll Thu Oct 9 20:27:02 2014
>> @@ -71,3 +71,50 @@ U:
>> T:
>> ret i32 2
>> }
>> +
>> +
>> +;; We can either convert the following control-flow to a select or remove the
>> +;; unreachable control flow because of the undef store of null. Make sure we do
>> +;; the latter.
>> +
>> +define void @test5(i1 %cond, i8* %ptr) {
>> +
>> +; CHECK-LABEL: test5
>> +; CHECK: entry:
>> +; CHECK-NOT: select
>> +; CHECK: store i8 2, i8* %ptr
>> +; CHECK: ret
>> +
>> +entry:
>> + br i1 %cond, label %bb1, label %bb3
>> +
>> +bb3:
>> + br label %bb2
>> +
>> +bb1:
>> + br label %bb2
>> +
>> +bb2:
>> + %ptr.2 = phi i8* [ %ptr, %bb3 ], [ null, %bb1 ]
>> + store i8 2, i8* %ptr.2, align 8
>> + ret void
>> +}
>> +
>> +; CHECK-LABEL: test6
>> +; CHECK: entry:
>> +; CHECK-NOT: select
>> +; CHECK: store i8 2, i8* %ptr
>> +; CHECK: ret
>> +
>> +define void @test6(i1 %cond, i8* %ptr) {
>> +entry:
>> + br i1 %cond, label %bb1, label %bb2
>> +
>> +bb1:
>> + br label %bb2
>> +
>> +bb2:
>> + %ptr.2 = phi i8* [ %ptr, %entry ], [ null, %bb1 ]
>> + store i8 2, i8* %ptr.2, align 8
>> + ret void
>> +}
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
More information about the llvm-commits
mailing list