What's the difference between target llvm and C?

I wonder why there are two codegen backend for cpu?

and also, when I want to see the C code generated, I got this error

TVMError: Unresolved call Op(tir.sqrt)

Here is my code:

N = 4
def get_func_abs():
    x = relay.var('x', shape=(N,), dtype='float32')
    x = relay.abs(x)

    a = relay.sqrt(x)
    b = relay.nn.relu(x)
    z = relay.add(a, b)
    return z

def test_relay_build():
    z = get_func_abs()
    func = relay.Function(relay.analysis.free_vars(z), z)

    module = tvm.IRModule.from_expr(func)
    print(module)
    target = tvm.target.Target(target="cuda")
    target = tvm.target.Target(target="llvm")
    target = tvm.target.Target(target="c")
    device = tvm.device(target.kind.name, 0)

    print(os.getpid())
    import pdb;pdb.set_trace()
    lib = relay.build_module.build(module, target, params=None)
    print(lib.lib.get_source())

TVM is a multi-backend re-targetable compiler, and Target in TVM means which backend to generate code to. In your particular case, the LLVM target means TVM generates LLVM IR and uses LLVM to generate binary artifacts; the C target means generating C source code.

thank you, do you know what the error message means ?

TVMError: Unresolved call Op(tir.sqrt)

I don’t think the C target is well supported, because there are wide range of tvm/llvm intrinsics that cannot be simply represented in ansi c. Please use the LLVM target if possible

thank you, I just want to see the generated C code for a relay model.

Seems the LLVM generates LLVM IR, that is not readable, is that right ?