[llvm-commits] [llvm] r59756 - /llvm/trunk/include/llvm/Intrinsics.td

Evan Cheng echeng at apple.com
Fri Nov 21 08:52:08 PST 2008


On Nov 21, 2008, at 5:56 AM, Duncan Sands wrote:

> Hi Evan,
>
>> Can codegen really handle i33 arithmetic?
>
> yes it can.  Check out this version of Bill's testcase (I've
> changed it to use unsigned addition).  The intrinsic version
> comes first, followed by the i33 version.
>
> ; RUN: llvm-as < %s | llc
>
> @ok = internal constant [4 x i8] c"%d\0A\00"
> @no = internal constant [4 x i8] c"no\0A\00"
>
> define i1 @foo(i32 %v1, i32 %v2) nounwind {
> entry:
>  %t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
>  %sum = extractvalue {i32, i1} %t, 0
>  %obit = extractvalue {i32, i1} %t, 1
>  br i1 %obit, label %overflow, label %normal
>
> normal:
>  %t1 = tail call i32 (i8*, ...)* @printf( i8* getelementptr ([4 x  
> i8]* @ok, i32 0, i32 0), i32 %sum ) nounwind
>  ret i1 true
>
> overflow:
>  %t2 = tail call i32 (i8*, ...)* @printf( i8* getelementptr ([4 x  
> i8]* @no, i32 0, i32 0) ) nounwind
>  ret i1 false
> }
>
> declare i32 @printf(i8*, ...) nounwind
> declare {i32, i1} @llvm.uadd.with.overflow.i32(i32, i32)
>
> define i1 @foo2(i32 %v1, i32 %v2) nounwind {
> entry:
>  %v1e = zext i32 %v1 to i33
>  %v2e = zext i32 %v2 to i33
>  %sume = add i33 %v1e, %v2e
>  %sum = trunc i33 %sume to i32
>  %tmp = lshr i33 %sume, 32
>  %obit = trunc i33 %tmp to i1
>  br i1 %obit, label %overflow, label %normal
>
> normal:
>  %t1 = tail call i32 (i8*, ...)* @printf( i8* getelementptr ([4 x  
> i8]* @ok, i32 0, i32 0), i32 %sum ) nounwind
>  ret i1 true
>
> overflow:
>  %t2 = tail call i32 (i8*, ...)* @printf( i8* getelementptr ([4 x  
> i8]* @no, i32 0, i32 0) ) nounwind
>  ret i1 false
> }
>
> declare i32 @printf(i8*, ...) nounwind
> declare {i32, i1} @llvm.uadd.with.overflow.i32(i32, i32)
>
>> Even if it does,
>> transforming it the ADDC / ADDO + check probably requires quite a bit
>> of work in dag combine. We'd also like to support it in fast-isel. I
>> think the intrinsics are needed, at least in the short term.
>
> Indeed, for the above i33 code you don't get a simple use of the carry
> flag on x86.  I'm sure you used to, so I guess something changed.  In
> any case the fact that you don't get a carry anymore at least proves  
> the
> fragility of expecting codegen to reliably use a carry!   As you  
> say, to
> make sure this happens consistently requires some work.  That said,  
> boosting
> the power of integer codegen is a win for everyone, while using an  
> intrinsic
> for overflow only helps those who use it.

This is a good idea. In the long run, we definitely should consider  
something like this so we can eliminate the intrinsics. However, we  
need these intrinsics for now, especially for fast-isel.

Also, I think both ADDO and ADDC need to exist for a little longer for  
practical reasons.

1. Not every target is modeling the physical condition flag in isel.  
X86 does. See EFLAGS.
2. Currently only the bottom up register pressure reduction scheduler  
is able to handle physical register dependency.

I would love to eliminate ADDC completely. But the first step should  
be to eliminate it from x86.

Evan

>
>
>> As for ADDC vs ADDO. I think we have come to the same conclusion. I
>> like to explicitly modeled the carry bit. In the end one of them
>> probably should be eliminated. But that may take a bit of effort.
>
> Yes.
>
> Ciao,
>
> Duncan.




More information about the llvm-commits mailing list