[cfe-dev] Bad IR involving the use of bzero

John McCall via cfe-dev cfe-dev at lists.llvm.org
Mon Nov 6 21:34:12 PST 2017


> On Nov 7, 2017, at 12:15 AM, Bharathi Seshadri via cfe-dev <cfe-dev at lists.llvm.org> wrote:
> 
> 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,
> Bharathi
> 
> -------------------------------------------------------------------------------
> 
> Index: CGBuiltin.cpp
> ===================================================================
> --- CGBuiltin.cpp       (revision 316884)
> +++ CGBuiltin.cpp       (working copy)
> @@ -1431,7 +1431,7 @@
>     EmitNonNullArgCheck(RValue::get(Dest.getPointer()),
> E->getArg(0)->getType(),
>                         E->getArg(0)->getExprLoc(), FD, 0);
>     Builder.CreateMemSet(Dest, Builder.getInt8(0), SizeVal, false);
> -    return RValue::get(Dest.getPointer());
> +    return RValue::get(nullptr);
>   }
>   case Builtin::BImemcpy:
>   case Builtin::BI__builtin_memcpy: {
> 
> The bad IR for the test case is :
> 
> define void @test_bzero() #0 {
> entry:
>  %dst = alloca [20 x i8], align 16
>  %_sz = alloca i32, align 4
>  %len = alloca i32, align 4
>  store i32 20, i32* %_sz, align 4
>  store i32 20, i32* %len, align 4
>  %0 = load i32, i32* %_sz, align 4
>  %tobool = icmp ne i32 %0, 0
>  br i1 %tobool, label %cond.true, label %cond.false2
> 
> cond.true:                                        ; preds = %entry
>  %1 = load i32, i32* %_sz, align 4
>  %2 = load i32, i32* %len, align 4
>  %cmp = icmp sge i32 %1, %2
>  br i1 %cmp, label %cond.true1, label %cond.false
> 
> cond.true1:                                       ; preds = %cond.true
>  %arraydecay = getelementptr inbounds [20 x i8], [20 x i8]* %dst, i32 0, i32 0
>  %3 = load i32, i32* %len, align 4
>  %conv = sext i32 %3 to i64
>  call void @llvm.memset.p0i8.i64(i8* %arraydecay, i8 0, i64 %conv,
> i32 16, i1 false)
>  br label %cond.end
> 
> cond.false:                                       ; preds = %cond.true
>  call void @foo()
>  br label %cond.end
> 
> cond.end:                                         ; preds =
> %cond.false, %cond.true1
>  br label %cond.end5
> 
> cond.false2:                                      ; preds = %entry
>  %arraydecay3 = getelementptr inbounds [20 x i8], [20 x i8]* %dst, i32 0, i32 0
>  %4 = load i32, i32* %len, align 4
>  %conv4 = sext i32 %4 to i64
>  call void @llvm.memset.p0i8.i64(i8* %arraydecay3, i8 0, i64 %conv4,
> i32 16, i1 false)
>  br label %cond.end5
> 
> cond.end5:                                        ; preds =
> %cond.false2, %cond.end
>  %cond = phi i8* [ %arraydecay, %cond.end ], [ %arraydecay3, %cond.false2 ]
>  ret void
> }
> 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!
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev




More information about the cfe-dev mailing list