Ok, I think I have a handle on the problem. The changes that cause this were introduced in R141177.

Take this basic block:

f.end: ; preds = %if.else, %if.then62, %if.then

%x.0 = phi i32 [ %conv, %if.then ], [ %tmp81, %if.then62 ], [ %tmp55, %if.else ]

%y.0 = phi i32 [ %conv37, %if.then ], [ %tmp71, %if.then62 ], [ %conv45, %if.else ]

…

%cmp106 = icmp eq i32 %x.0, %y.0

br i1 %cmp106, label %if.then108, label %if.else109

When processing the branch instruction, GVN somehow thinks that it is safe to switch %y.0 for %x.0

Here is if.then108:

if.then108: ; preds = %if.end

br i1 %cmp83, label %if.then113, label %if.end112

Here is if.end112:

if.end112: ; preds = %if.then113, %if.then108

tail call void @barrier(i32 0, i32 1) nounwind

%cmp151 = icmp ult i32 %tmp95, 216

%tmp153 = shl i32 %x.0, 5

%tmp155 = or i32 %., %tmp153

%tmp209 = extractelement <4 x float> %tmp99, i32 0

%tmp210 = insertelement <3 x float> undef, float %tmp209, i32 0

%tmp211 = extractelement <4 x float> %tmp99, i32 1

%tmp212 = insertelement <3 x float> %tmp210, float %tmp211, i32 1

%tmp213 = extractelement <4 x float> %tmp99, i32 2

%tmp214 = insertelement <3 x float> %tmp212, float %tmp213, i32 2

%tmp279 = extractelement <4 x float> %tmp99, i32 3

%tmp280 = fmul float %tmp279, 0xC061252760000000

br label %for.body

Somehow, this optimization on the br instruction is turning

%tmp153 = shl i32 %y.0, 5

into

%tmp153 = shl i32 %x.0, 5

breaking our applications.

My proposed solution is to add this to propagateEquality:

// Don’t try to propogate equalities between phi nodes.

if (isa(LHS) || isa(RHS)) continue;

The only other thing I can think of is that isOnlyReachableViaThisEdge has a bug in its logic in this case.

Micah