diff --git a/lib/Target/README.txt b/lib/Target/README.txt index c0a2b760de7..b3bc7498566 100644 --- a/lib/Target/README.txt +++ b/lib/Target/README.txt @@ -2274,3 +2274,51 @@ llc time when it gets inlined, because we can use smaller transfers. This also avoids partial register stalls in some important cases. //===---------------------------------------------------------------------===// + +With PR8575 we're now generating better code for: + +static _Bool foo(int x) { return x == 1; } +static _Bool bar(int x) { return x == 2; } +static _Bool baz(int x) { return x == 3; } + +_Bool quux(int x) { + return foo(x) || bar(x) || baz(x); +} + +$ clang t.c -S -o - -O3 -mkernel -fomit-frame-pointer +_quux: ## @quux +## BB#0: ## %entry + decl %edi + cmpl $3, %edi + movb $1, %al + jb LBB0_2 +## BB#1: ## %lor.rhs + xorb %al, %al +LBB0_2: ## %lor.end + movzbl %al, %eax + andl $1, %eax + ret + +But this should use a "setcc" instead of materializing a 0/1 value +the hard way. This looks like #1: simplifycfg should transform the +switch into a sub+icmp+branch, and an instcombine hack to replace +the PHI with a zext of the branch condition. Here's the IR today: + +define zeroext i1 @quux(i32 %x) nounwind readnone ssp noredzone { +entry: + switch i32 %x, label %lor.rhs [ + i32 1, label %lor.end + i32 2, label %lor.end + i32 3, label %lor.end + ] + +lor.rhs: ; preds = %entry + br label %lor.end + +lor.end: ; preds = %lor.rhs, %entry, %entry, %entry + %0 = phi i1 [ true, %entry ], [ false, %lor.rhs ], [ true, %entry ], [ true, %entry ] + ret i1 %0 +} + +//===---------------------------------------------------------------------===// +