private void AddBarrierDivergenceCandidates(HashSet <Variable> localVars, Implementation impl, IRegion region) { if (!verifier.ContainsBarrierCall(region) && !GPUVerifyVCGenCommandLineOptions.WarpSync) { return; } Expr guard = region.Guard(); if (guard != null && verifier.UniformityAnalyser.IsUniform(impl.Name, guard)) { return; } if (IsDisjunctionOfPredicates(guard)) { string loopPredicate = ((guard as NAryExpr).Args[0] as IdentifierExpr).Name; loopPredicate = loopPredicate.Substring(0, loopPredicate.IndexOf('$')); // Int type used here, but it doesn't matter as we will print and then re-parse the program var uniformEnabledPredicate = Expr.Eq( new IdentifierExpr(Token.NoToken, new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, loopPredicate + "$1", Type.Int))), new IdentifierExpr(Token.NoToken, new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, loopPredicate + "$2", Type.Int)))); verifier.AddCandidateInvariant(region, uniformEnabledPredicate, "loopPredicateEquality"); verifier.AddCandidateInvariant(region, Expr.Imp(verifier.ThreadsInSameGroup(), uniformEnabledPredicate), "loopPredicateEquality"); Dictionary <string, int> assignmentCounts = GetAssignmentCounts(impl); HashSet <string> alreadyConsidered = new HashSet <string>(); foreach (var v in localVars) { string lv = Utilities.StripThreadIdentifier(v.Name); if (alreadyConsidered.Contains(lv)) { continue; } alreadyConsidered.Add(lv); if (verifier.UniformityAnalyser.IsUniform(impl.Name, v.Name)) { continue; } if (GPUVerifier.IsPredicate(lv)) { continue; } if (!assignmentCounts.ContainsKey(lv) || assignmentCounts[lv] <= 1) { continue; } if (!verifier.ContainsNamedVariable(region.GetModifiedVariables(), lv)) { continue; } AddPredicatedEqualityCandidateInvariant(region, loopPredicate, new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, lv, Type.Int))); } } }