Bad IR involving the use of bzero

I am seeing an issue that seems to be specific to the use of bzero as below.

bash-4.1$ cat test.c

typedef __SIZE_TYPE__ size_t;
void bzero(void*, size_t);
void foo(void);

void test_bzero() {
  char dst[20];
  int _sz = 20, len = 20;
  return (_sz
          ? ((_sz >= len)
             ? bzero(dst, len)
             : foo())
          : bzero(dst, len));
}

Compiling this test case results in the following error:

I am seeing an issue that seems to be specific to the use of bzero as below.

bash-4.1$ cat test.c

typedef __SIZE_TYPE__ size_t;
void bzero(void*, size_t);
void foo(void);

void test_bzero() {
char dst[20];
int _sz = 20, len = 20;
return (_sz
         ? ((_sz >= len)
            ? bzero(dst, len)
            : foo())
         : bzero(dst, len));
}

Compiling this test case results in the following error:
---------
Instruction does not dominate all uses!
%arraydecay = getelementptr inbounds [20 x i8], [20 x i8]* %dst, i32 0, i32 0
%cond = phi i8* [ %arraydecay, %cond.end ], [ %arraydecay3, %cond.false2 ]
fatal error: error in backend: Broken function found, compilation aborted!
---------

Inspecting the IR (see below), the generation of Phi node appears to
be incorrect. It seems to me
that the phi node (for merging dst) is rather unnecessary since bzero
returns void.
In EmitBuiltinExpr(), bzero is replaced by a call to memset, which
returns a pointer to the destination.
Here is a patch that fixes the issue. (The llvm test suite and spec
runs are succcessful with the patch).

Is this patch reasonable? If not, could some one advice where the
issue is likely to be?

The patch is reasonable. "Returning" a value here is triggering code that is supposed
to be suppressed when the return value is void, but it only ends up mattering inside a
conditional operator.

If you wouldn't mind formalizing your test case above into a real lit test case, we can
commit your fix.

John.

Thanks John.

I've posted the patch for review: https://reviews.llvm.org/D39746

Bharathi