Index: include/llvm/IR/IntrinsicsARM.td =================================================================== --- include/llvm/IR/IntrinsicsARM.td +++ include/llvm/IR/IntrinsicsARM.td @@ -262,59 +262,59 @@ // Coprocessor def int_arm_ldc : GCCBuiltin<"__builtin_arm_ldc">, - Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], []>; + Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], [ImmArg<0>, ImmArg<1>]>; def int_arm_ldcl : GCCBuiltin<"__builtin_arm_ldcl">, - Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], []>; + Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], [ImmArg<0>, ImmArg<1>]>; def int_arm_ldc2 : GCCBuiltin<"__builtin_arm_ldc2">, - Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], []>; + Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], [ImmArg<0>, ImmArg<1>]>; def int_arm_ldc2l : GCCBuiltin<"__builtin_arm_ldc2l">, - Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], []>; + Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], [ImmArg<0>, ImmArg<1>]>; def int_arm_stc : GCCBuiltin<"__builtin_arm_stc">, - Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], []>; + Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], [ImmArg<0>, ImmArg<1>]>; def int_arm_stcl : GCCBuiltin<"__builtin_arm_stcl">, - Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], []>; + Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], [ImmArg<0>, ImmArg<1>]>; def int_arm_stc2 : GCCBuiltin<"__builtin_arm_stc2">, - Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], []>; + Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], [ImmArg<0>, ImmArg<1>]>; def int_arm_stc2l : GCCBuiltin<"__builtin_arm_stc2l">, - Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], []>; + Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], [ImmArg<0>, ImmArg<1>]>; // Move to coprocessor def int_arm_mcr : GCCBuiltin<"__builtin_arm_mcr">, Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, - llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>; + llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [ImmArg<0>, ImmArg<1>, ImmArg<3>, ImmArg<4>, ImmArg<5>]>; def int_arm_mcr2 : GCCBuiltin<"__builtin_arm_mcr2">, Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, - llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>; + llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [ImmArg<0>, ImmArg<1>, ImmArg<3>, ImmArg<4>, ImmArg<5>]>; // Move from coprocessor def int_arm_mrc : GCCBuiltin<"__builtin_arm_mrc">, MSBuiltin<"_MoveFromCoprocessor">, Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, - llvm_i32_ty, llvm_i32_ty], []>; + llvm_i32_ty, llvm_i32_ty], [ImmArg<0>, ImmArg<1>, ImmArg<2>, ImmArg<3>, ImmArg<4>]>; def int_arm_mrc2 : GCCBuiltin<"__builtin_arm_mrc2">, MSBuiltin<"_MoveFromCoprocessor2">, Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, - llvm_i32_ty, llvm_i32_ty], []>; + llvm_i32_ty, llvm_i32_ty], [ImmArg<0>, ImmArg<1>, ImmArg<2>, ImmArg<3>, ImmArg<4>]>; // Coprocessor data processing def int_arm_cdp : GCCBuiltin<"__builtin_arm_cdp">, Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, - llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>; + llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [ImmArg<0>, ImmArg<1>, ImmArg<2>, ImmArg<3>, ImmArg<4>, ImmArg<5>]>; def int_arm_cdp2 : GCCBuiltin<"__builtin_arm_cdp2">, Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, - llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>; + llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [ImmArg<0>, ImmArg<1>, ImmArg<2>, ImmArg<3>, ImmArg<4>, ImmArg<5>]>; // Move from two registers to coprocessor def int_arm_mcrr : Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, - llvm_i32_ty, llvm_i32_ty], []>; + llvm_i32_ty, llvm_i32_ty], [ImmArg<0>, ImmArg<1>, ImmArg<2>, ImmArg<3>, ImmArg<4>]>; def int_arm_mcrr2 : Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, - llvm_i32_ty, llvm_i32_ty], []>; + llvm_i32_ty, llvm_i32_ty], [ImmArg<0>, ImmArg<1>, ImmArg<2>, ImmArg<3>, ImmArg<4>]>; def int_arm_mrrc : Intrinsic<[llvm_i32_ty, llvm_i32_ty], [llvm_i32_ty, - llvm_i32_ty, llvm_i32_ty], []>; + llvm_i32_ty, llvm_i32_ty], [ImmArg<0>, ImmArg<1>, ImmArg<2>]>; def int_arm_mrrc2 : Intrinsic<[llvm_i32_ty, llvm_i32_ty], [llvm_i32_ty, - llvm_i32_ty, llvm_i32_ty], []>; + llvm_i32_ty, llvm_i32_ty], [ImmArg<0>, ImmArg<1>, ImmArg<2>]>; //===----------------------------------------------------------------------===// // CRC32 Index: test/CodeGen/ARM/cdp.ll =================================================================== --- test/CodeGen/ARM/cdp.ll +++ /dev/null @@ -1,13 +0,0 @@ -; RUN: not llc < %s -mtriple=armv7-eabi -mcpu=cortex-a8 2>&1 | FileCheck %s -; RUN: not llc < %s -mtriple=thumbv7-eabi -mcpu=cortex-a8 2>&1 | FileCheck %s - -; CHECK: LLVM ERROR: Cannot select: intrinsic %llvm.arm.cdp -define void @cdp(i32 %a) #0 { - %a.addr = alloca i32, align 4 - store i32 %a, i32* %a.addr, align 4 - %1 = load i32, i32* %a.addr, align 4 - call void @llvm.arm.cdp(i32 %1, i32 2, i32 3, i32 4, i32 5, i32 6) - ret void -} - -declare void @llvm.arm.cdp(i32, i32, i32, i32, i32, i32) nounwind Index: test/CodeGen/ARM/cdp2.ll =================================================================== --- test/CodeGen/ARM/cdp2.ll +++ /dev/null @@ -1,13 +0,0 @@ -; RUN: not llc < %s -mtriple=armv7-eabi -mcpu=cortex-a8 2>&1 | FileCheck %s -; RUN: not llc < %s -mtriple=thumbv7-eabi -mcpu=cortex-a8 2>&1 | FileCheck %s - -; CHECK: LLVM ERROR: Cannot select: intrinsic %llvm.arm.cdp2 -define void @cdp2(i32 %a) #0 { - %a.addr = alloca i32, align 4 - store i32 %a, i32* %a.addr, align 4 - %1 = load i32, i32* %a.addr, align 4 - call void @llvm.arm.cdp2(i32 %1, i32 2, i32 3, i32 4, i32 5, i32 6) - ret void -} - -declare void @llvm.arm.cdp2(i32, i32, i32, i32, i32, i32) nounwind Index: test/Verifier/ARM/intrinsic-immarg.ll =================================================================== --- /dev/null +++ test/Verifier/ARM/intrinsic-immarg.ll @@ -0,0 +1,122 @@ +; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s + +declare void @llvm.arm.cdp(i32, i32, i32, i32, i32, i32) nounwind + +define void @cdp(i32 %a) #0 { + ; CHECK: immarg operand has non-immediate parameter + ; CHECK-NEXT: %load = load i32, i32* %a.addr, align 4 + ; CHECK-NEXT: call void @llvm.arm.cdp(i32 %load, i32 2, i32 3, i32 4, i32 5, i32 6) + %a.addr = alloca i32, align 4 + store i32 %a, i32* %a.addr, align 4 + %load = load i32, i32* %a.addr, align 4 + call void @llvm.arm.cdp(i32 %load, i32 2, i32 3, i32 4, i32 5, i32 6) + ret void +} + +declare void @llvm.arm.cdp2(i32, i32, i32, i32, i32, i32) nounwind +define void @cdp2(i32 %a) #0 { + ; CHECK: immarg operand has non-immediate parameter + ; CHECK-NEXT: %load = load i32, i32* %a.addr, align 4 + ; CHECK-NEXT: call void @llvm.arm.cdp2(i32 %load, i32 2, i32 3, i32 4, i32 5, i32 6) + %a.addr = alloca i32, align 4 + store i32 %a, i32* %a.addr, align 4 + %load = load i32, i32* %a.addr, align 4 + call void @llvm.arm.cdp2(i32 %load, i32 2, i32 3, i32 4, i32 5, i32 6) + ret void +} + +declare { i32, i32 } @llvm.arm.mrrc(i32, i32, i32) nounwind +define void @mrrc(i32 %arg0, i32 %arg1, i32 %arg2) #0 { + ; CHECK: immarg operand has non-immediate parameter + ; CHECK-NEXT: i32 %arg0 + ; CHECK-NEXT: %ret0 = call { i32, i32 } @llvm.arm.mrrc(i32 %arg0, i32 0, i32 0) + %ret0 = call { i32, i32 } @llvm.arm.mrrc(i32 %arg0, i32 0, i32 0) + + ; CHECK: immarg operand has non-immediate parameter + ; CHECK-NEXT: i32 %arg1 + ; CHECK-NEXT: %ret1 = call { i32, i32 } @llvm.arm.mrrc(i32 0, i32 %arg1, i32 0) + %ret1 = call { i32, i32 } @llvm.arm.mrrc(i32 0, i32 %arg1, i32 0) + + ; CHECK: immarg operand has non-immediate parameter + ; CHECK-NEXT: i32 %arg2 + ; CHECK-NEXT: %ret2 = call { i32, i32 } @llvm.arm.mrrc(i32 0, i32 0, i32 %arg2) + %ret2 = call { i32, i32 } @llvm.arm.mrrc(i32 0, i32 0, i32 %arg2) + ret void +} + +declare { i32, i32 } @llvm.arm.mrrc2(i32, i32, i32) nounwind +define void @mrrc2(i32 %arg0, i32 %arg1, i32 %arg2) #0 { + ; CHECK: immarg operand has non-immediate parameter + ; CHECK-NEXT: i32 %arg0 + ; CHECK-NEXT: %ret0 = call { i32, i32 } @llvm.arm.mrrc2(i32 %arg0, i32 0, i32 0) + %ret0 = call { i32, i32 } @llvm.arm.mrrc2(i32 %arg0, i32 0, i32 0) + + ; CHECK: immarg operand has non-immediate parameter + ; CHECK-NEXT: i32 %arg1 + ; CHECK-NEXT: %ret1 = call { i32, i32 } @llvm.arm.mrrc2(i32 0, i32 %arg1, i32 0) + %ret1 = call { i32, i32 } @llvm.arm.mrrc2(i32 0, i32 %arg1, i32 0) + + ; CHECK: immarg operand has non-immediate parameter + ; CHECK-NEXT: i32 %arg2 + ; CHECK-NEXT: %ret2 = call { i32, i32 } @llvm.arm.mrrc2(i32 0, i32 0, i32 %arg2) + %ret2 = call { i32, i32 } @llvm.arm.mrrc2(i32 0, i32 0, i32 %arg2) + ret void +} + +declare void @llvm.arm.mcrr(i32, i32, i32, i32, i32) nounwind +define void @mcrr(i32 %arg0, i32 %arg1, i32 %arg2, i32 %arg3, i32 %arg4) { + ; CHECK: immarg operand has non-immediate parameter + ; CHECK-NEXT: i32 %arg0 + ; CHECK-NEXT: call void @llvm.arm.mcrr(i32 %arg0, i32 1, i32 2, i32 3, i32 4) + call void @llvm.arm.mcrr(i32 %arg0, i32 1, i32 2, i32 3, i32 4) + + ; CHECK: immarg operand has non-immediate parameter + ; CHECK-NEXT: i32 %arg1 + ; CHECK-NEXT: call void @llvm.arm.mcrr(i32 0, i32 %arg1, i32 2, i32 3, i32 4) + call void @llvm.arm.mcrr(i32 0, i32 %arg1, i32 2, i32 3, i32 4) + + ; CHECK: immarg operand has non-immediate parameter + ; CHECK-NEXT: i32 %arg2 + ; CHECK-NEXT: call void @llvm.arm.mcrr(i32 0, i32 1, i32 %arg2, i32 3, i32 4) + call void @llvm.arm.mcrr(i32 0, i32 1, i32 %arg2, i32 3, i32 4) + + ; CHECK: immarg operand has non-immediate parameter + ; CHECK-NEXT: i32 %arg3 + ; CHECK-NEXT: call void @llvm.arm.mcrr(i32 0, i32 1, i32 2, i32 %arg3, i32 4) + call void @llvm.arm.mcrr(i32 0, i32 1, i32 2, i32 %arg3, i32 4) + + ; CHECK: immarg operand has non-immediate parameter + ; CHECK-NEXT: i32 %arg4 + ; CHECK-NEXT: call void @llvm.arm.mcrr(i32 0, i32 1, i32 2, i32 3, i32 %arg4) + call void @llvm.arm.mcrr(i32 0, i32 1, i32 2, i32 3, i32 %arg4) + ret void +} + +declare void @llvm.arm.mcrr2(i32, i32, i32, i32, i32) nounwind +define void @mcrr2(i32 %arg0, i32 %arg1, i32 %arg2, i32 %arg3, i32 %arg4) { + ; CHECK: immarg operand has non-immediate parameter + ; CHECK-NEXT: i32 %arg0 + ; CHECK-NEXT: call void @llvm.arm.mcrr2(i32 %arg0, i32 1, i32 2, i32 3, i32 4) + call void @llvm.arm.mcrr2(i32 %arg0, i32 1, i32 2, i32 3, i32 4) + + ; CHECK: immarg operand has non-immediate parameter + ; CHECK-NEXT: i32 %arg1 + ; CHECK-NEXT: call void @llvm.arm.mcrr2(i32 0, i32 %arg1, i32 2, i32 3, i32 4) + call void @llvm.arm.mcrr2(i32 0, i32 %arg1, i32 2, i32 3, i32 4) + + ; CHECK: immarg operand has non-immediate parameter + ; CHECK-NEXT: i32 %arg2 + ; CHECK-NEXT: call void @llvm.arm.mcrr2(i32 0, i32 1, i32 %arg2, i32 3, i32 4) + call void @llvm.arm.mcrr2(i32 0, i32 1, i32 %arg2, i32 3, i32 4) + + ; CHECK: immarg operand has non-immediate parameter + ; CHECK-NEXT: i32 %arg3 + ; CHECK-NEXT: call void @llvm.arm.mcrr2(i32 0, i32 1, i32 2, i32 %arg3, i32 4) + call void @llvm.arm.mcrr2(i32 0, i32 1, i32 2, i32 %arg3, i32 4) + + ; CHECK: immarg operand has non-immediate parameter + ; CHECK-NEXT: i32 %arg4 + ; CHECK-NEXT: call void @llvm.arm.mcrr2(i32 0, i32 1, i32 2, i32 3, i32 %arg4) + call void @llvm.arm.mcrr2(i32 0, i32 1, i32 2, i32 3, i32 %arg4) + ret void +} Index: test/Verifier/ARM/lit.local.cfg =================================================================== --- /dev/null +++ test/Verifier/ARM/lit.local.cfg @@ -0,0 +1,2 @@ +if not 'ARM' in config.root.targets: + config.unsupported = True