[LLVMdev] Lowering intrinsics / type promotion

Martin Filteau martin.filteau at octasic.com
Tue Apr 16 12:06:15 PDT 2013


Hi!

I'm not sure how to handle intrinsic functions that have non-i32 operands.  The target only supports 32-bit registers natively but for some operations, only the lower 16 bits are significant.

For example, the SMULS instruction does a 16 x 16 fractional multiply with saturation.  I've defined an intrinsic function:

int __builtin_opus_smuls(short a, short b);

def int_opus_smuls : GCCBuiltin<"__builtin_opus_smuls">,
    Intrinsic<[llvm_i32_ty], [llvm_i16_ty, llvm_i16_ty],
    [IntrNoMem]>;


; ModuleID = 'test.c'
target datalayout = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-n32"
target triple = "opus-octasic-unknownos"

@a = common global i16 0, align 2
@b = common global i16 0, align 2

define i32 @main() #0 {
entry:
  %retval = alloca i32, align 4
  store i32 0, i32* %retval
  %0 = load i16* @a, align 4
  %1 = load i16* @b, align 2
  %2 = call i32 @llvm.opus.smuls(i16 %0, i16 %1)
  ret i32 %2
}

declare i32 @llvm.opus.smuls(i16, i16) #1

PromoteIntegerOperand Op #1: 0x33f090: i32 = llvm.opus.smuls 0x33f008, 0x33ee70, 0x33ef80 [ORD=4] [ID=0]

Do not know how to promote this operator's operand!
UNREACHABLE executed at ..\..\..\..\lib\CodeGen\SelectionDAG\LegalizeIntegerTypes.cpp:763!

I've tried adding a custom LowerINTRINSIC_WO_CHAIN handler. What's the right way of doing this?

Thanks,

-Martin





More information about the llvm-dev mailing list