On Oct 22, 2008, at 10:45 PM, Duncan Sands wrote:>> Can't you implement __builtin_assume(cond) to codegen to something >> like: >> >> %cond = i1 ... >> br i1 %cond, label %always, label %never >> never: >> unreachable >> always: > > The code generators will remove the branch to %never. > I already tried this :) What would work is to define > an llvm.abort intrinsic, and do: > > %cond = i1 ... > br i1 %cond, label %always, label %never > never: > call void @llvm.abort() > unreachable > > At codegen time @llvm.abort() can be lowered to > nothing at all. I'm not saying that this is my > favorite solution, but it is simple.How is this different than just branching to unreachable? Branching to unreachable says that "this condition is true or else the program has undefined behavior". This means that the condition must be true :) -Chris
> > %cond = i1 ... > > br i1 %cond, label %always, label %never > > never: > > call void @llvm.abort() > > unreachable > > > > At codegen time @llvm.abort() can be lowered to > > nothing at all. I'm not saying that this is my > > favorite solution, but it is simple. > > How is this different than just branching to unreachable? Branching > to unreachable says that "this condition is true or else the program > has undefined behavior". This means that the condition must be true :)The difference is that simplifycfg will remove the branch to %never if %never only contains unreachable. The role of the intrinsic call is to fool simplifycfg into not doing this! Ciao, Duncan.
On Thu, Oct 23, 2008 at 8:23 AM, Duncan Sands <baldrick at free.fr> wrote:>> > %cond = i1 ... >> > br i1 %cond, label %always, label %never >> > never: >> > call void @llvm.abort() >> > unreachable >> > >> > At codegen time @llvm.abort() can be lowered to >> > nothing at all. I'm not saying that this is my >> > favorite solution, but it is simple. >> >> How is this different than just branching to unreachable? Branching >> to unreachable says that "this condition is true or else the program >> has undefined behavior". This means that the condition must be true :) > > The difference is that simplifycfg will remove the branch > to %never if %never only contains unreachable. The role > of the intrinsic call is to fool simplifycfg into not > doing this!This certainly sounds like the simplest approach, even though it adds an intrinsic. Is there general interest in adding this? Thanks, Paul -- Paul Biggar paul.biggar at gmail.com
On Oct 23, 2008, at 12:23 AM, Duncan Sands wrote:>>> %cond = i1 ... >>> br i1 %cond, label %always, label %never >>> never: >>> call void @llvm.abort() >>> unreachable >>> >>> At codegen time @llvm.abort() can be lowered to >>> nothing at all. I'm not saying that this is my >>> favorite solution, but it is simple. >> >> How is this different than just branching to unreachable? Branching >> to unreachable says that "this condition is true or else the program >> has undefined behavior". This means that the condition must be >> true :) > > The difference is that simplifycfg will remove the branch > to %never if %never only contains unreachable. The role > of the intrinsic call is to fool simplifycfg into not > doing this!Sounds like the "bug" is in simplifycfg then. The IR is already fully capable of expressing this without a new builtin. Note that these annotations would have to be removed *sometime* in the optimizer pipeline, the policy decision is picking a place. -Chris