Llvm : understanding hasAddressTaken

In LLVM, the member function hasAddressaken under the basic block is defined as follows:

bool hasAddressTaken () const
Returns true if there are any uses of this basic block other than direct branches, switches, etc. More…

So I tried to implement an indirect call branch, and I inserted a call instruction into each basic block.

; Function Attrs: noinline nounwind optnone uwtable
define dso_local i32 @print() #0 {
  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i32 0, i32 0))
  ret i32 0

declare dso_local i32 @printf(i8*, ...) #1

; Function Attrs: noinline nounwind optnone uwtable
define dso_local i32 @main() #0 {
  %retval = alloca i32, align 4
  %i = alloca i32, align 4
  %a = alloca [10 x i32], align 16
  store i32 0, i32* %retval, align 4
  store i32 0, i32* %i, align 4
  %0 = bitcast [10 x i32]* %a to i8*
  call void @llvm.memset.p0i8.i64(i8* align 16 %0, i8 0, i64 40, i1 false)
  store i32 0, i32* %i, align 4
  %1 = call i32 @print()
  br label %for.cond

for.cond:                                         ; preds = %for.inc, %entry
  %2 = load i32, i32* %i, align 4
  %cmp = icmp slt i32 %2, 20
  %3 = call i32 @print()
  br i1 %cmp, label %for.body, label %for.end

The print function defined at the beginning is called once in each basic block. But even then, hasAddressTaken returns false. Can anyone help me understand the definition of this function, or what I should do to make it return true?

First, your program does not contain any indirect branches, but only direct calls to the function print (and memset). In those cases you are calling functions, but not basic blocks. The addresses of Basic blocks are never taken (not even the entry blocks of the function)

To get the address of a Basic Block one needs to use the blockaddress constant/instruction:

As far as I can tell, hasAddressTaken() should then return true. The use of these kind of instructions, and blocks having addresses and subclassing llvm::Value is to be able to implement computed goto.
Clang implements this kind of extension in C or C++ as a GCC compatible feature eg. Compiler Explorer

1 Like

Got it!Thanks!