[LLVMdev] Add/sub with carry; widening multiply

Jonathan Brandmeyer jbrandmeyer at earthlink.net
Wed Nov 21 11:31:04 PST 2007

I've been playing around with llvm lately and I was wondering something about the bitcode instructions for basic arithmetic.  Is there any plan to provide instructions that perform widening multiply, or add with carry?  It might be written as:

mulw i32 %lhs %rhs -> i64 ; widening multiply
addw i32 %lhs %rhs -> i33 ; widening add
addc i32 %lhs, i32 %rhs, i1 %c -> i33 ; add with carry

Alternatively, would something like following get reduced to a single multiply and two stores on arch's that support wide multiplies, like x86-32 and ARM?

define void @mulw(i32* hidest, i32* lodest, i32 lhs, i32 rhs) {
  %0 = sext i32 %lhs to i64
  %1 = sext i32 %rhs to i64
  %2 = mul i64 %0 %1
  %3 = trunc i64 %2 to i32
  %4 = lshr i64 %2, 32
  %5 = truc i64 %4 to i32
  store i32 %3, i32* %lodest
  store i32 %5, i32* %hidest
  ret void

Another alternative could rely on multiple return values to return both the low and high words and/or carry bit separately.
%0, %1 = subc i32 %lhs, i32 %rhs, i1 %borrow -> i32, i1 ; subtract including borrow, returning result and borrow flag
%0, %1 = adc i32 %lhs, i32 %rhs, i1 %carry -> i32, i1 ; add with carry, returning result and carry

Has anything like this been considered in the past?

-Jonathan Brandmeyer

More information about the llvm-dev mailing list