[cfe-dev] questions about expansion of builtins.

Iain Sandoe iain at codesourcery.com
Fri Sep 13 12:19:54 PDT 2013


Hello folks,

I am working on an out-of-tree port that would, for some cases, like to expand builtins to multiple BBs.

So far, I've not succeeded in finding any guidance other than the code in CGBuiltin.cpp, Builtin.def, SemaChecking.cpp etc. (specifically, there doesn't appear to be anything in the internals doc.)

For simple builtins that, effectively, just pass the buck to LLVM for expansion at lower-to-asm time everything works fine.  The problems start when they generate BBs as part of the expansion.

----

To try and understand things better, I made a simplistic example "__factorial()" built-in that should be applicable to any port.

The code for this is attached, along with a driver program; this is set up for X86 so that folks can explore it for themselves [perhaps also this might form the basis of a documentation example, if appropriate].  The CG follows, I hope, the advice of the FE tutorial, although - of course - it could be missing some vital point …

----

OK, so having established that the example is trivial and only intended for illustration; nevertheless, it does exhibit the same issues I see with my real-world builtins.  

Note also that, while one could just as well replace the trivial example here with an inlined function, that is not true of the 'real-world' built-ins I'm trying to expand (part of the job is to overload the CG for different operand types).

----

What I find is that for -O0/O1 the CG behaves as expected - producing (at O1) what looks like correct (and is functional) IR to me:

; Function Attrs: noinline nounwind readnone ssp uwtable
define i32 @foo(i32 %x) #0 {
entry:
  %nothing.to.do = icmp ult i32 %x, 2
  %init.res = select i1 %nothing.to.do, i32 1, i32 %x
  br i1 %nothing.to.do, label %finished, label %fact_loop

fact_loop:                                        ; preds = %entry, %fact_loop
  %arg.0 = phi i32 [ %fact.prod, %fact_loop ], [ %init.res, %entry ]
  %tmp.0 = phi i32 [ %tmp.dec, %fact_loop ], [ %x, %entry ]
  %tmp.dec = add i32 %tmp.0, -1
  %fact.prod = mul i32 %tmp.dec, %arg.0
  %done = icmp ult i32 %tmp.dec, 2
  br i1 %done, label %finished, label %fact_loop

finished:                                         ; preds = %fact_loop, %entry
  %arg.1 = phi i32 [ %init.res, %entry ], [ %fact.prod, %fact_loop ]
  ret i32 %arg.1
}

==== problems:

(1) If I try to compile with debug enabled (regardless of optimisation level) I get:

$ ./Debug+Asserts/bin/clang ../fract.c -g -emit-llvm -S
Assertion failed: (unsigned(ScopeIdx) <= Ctx.pImpl->ScopeRecords.size() && "Invalid ScopeIdx!"), function getScopeAndInlinedAt, file /Volumes/sc2_src/llvm-trunk/lib/IR/DebugLoc.cpp, line 60.
0  clang             0x00000001031b721b llvm::sys::PrintStackTrace(__sFILE*) + 38

(2) If I try to compile -O2, then I get:

$ ./Debug+Asserts/bin/clang ../fract.c -O2 -emit-llvm -S
Assertion failed: (LHS->getType() == RHS->getType() && "Equality but unequal types!"), function propagateEquality, file /Volumes/sc2_src/llvm-trunk/lib/Transforms/Scalar/GVN.cpp, line 2045.
0  clang             0x000000010bac521b llvm::sys::PrintStackTrace(__sFILE*) + 38

Neither case is proving tractable to analysis (at least by me) mainly, because I'm not sure what the "correct" scenario should be.

===== Initial questions:

(of course, any pointers to mistakes in my coding assumptions equally welcome).

1. Is it reasonable to expect to be able to expand a built-in in this manner?

2. Is there some decoration (for debug at least) needed to label the expansion as belonging to the function that has, effectively, become inlined?

3. Any hints about where to start with the O2 problem would be appreciated - although there seems little point in persuing that until 1 and 2 are resolved.

Thanks,
Iain

The patch applies to TOT as of 2 hrs ago.
if one does "clang fract.c -O1 -o fract " [-O0 or -O1] then it should produce a working code - at least on x86.

-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: tmp-x86-diff.txt
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20130913/3a001887/attachment.txt>
-------------- next part --------------

-------------- next part --------------
A non-text attachment was scrubbed...
Name: fract.c
Type: application/octet-stream
Size: 280 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20130913/3a001887/attachment.obj>
-------------- next part --------------




More information about the cfe-dev mailing list