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

Duncan Sands baldrick at free.fr
Fri Nov 21 05:56:06 PST 2008


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.

> 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