Index: docs/StackMaps.rst =================================================================== --- docs/StackMaps.rst +++ docs/StackMaps.rst @@ -192,6 +192,9 @@ declare i64 @llvm.experimental.patchpoint.i64(i64 , i32 , i8* , i32 , ...) + declare double + @llvm.experimental.patchpoint.double(i64 , i32 , + i8* , i32 , ...) Overview: """"""""" Index: include/llvm/IR/Intrinsics.td =================================================================== --- include/llvm/IR/Intrinsics.td +++ include/llvm/IR/Intrinsics.td @@ -490,6 +490,11 @@ llvm_ptr_ty, llvm_i32_ty, llvm_vararg_ty], [Throws]>; +def int_experimental_patchpoint_double : Intrinsic<[llvm_double_ty], + [llvm_i64_ty, llvm_i32_ty, + llvm_ptr_ty, llvm_i32_ty, + llvm_vararg_ty], + [Throws]>; //===-------------------------- Other Intrinsics --------------------------===// // Index: lib/CodeGen/SelectionDAG/FastISel.cpp =================================================================== --- lib/CodeGen/SelectionDAG/FastISel.cpp +++ lib/CodeGen/SelectionDAG/FastISel.cpp @@ -738,7 +738,12 @@ // Add an explicit result reg if we use the anyreg calling convention. if (IsAnyRegCC && HasDef) { assert(CLI.NumResultRegs == 0 && "Unexpected result register."); - CLI.ResultReg = createResultReg(TLI.getRegClassFor(MVT::i64)); + if (I->getType()->isIntegerTy(64)) + CLI.ResultReg = createResultReg(TLI.getRegClassFor(MVT::i64)); + else if (I->getType()->isDoubleTy()) + CLI.ResultReg = createResultReg(TLI.getRegClassFor(MVT::f64)); + else + llvm_unreachable("unsupported patchpoint type"); CLI.NumResultRegs = 1; Ops.push_back(MachineOperand::CreateReg(CLI.ResultReg, /*IsDef=*/true)); } @@ -1205,6 +1210,7 @@ return selectStackmap(II); case Intrinsic::experimental_patchpoint_void: case Intrinsic::experimental_patchpoint_i64: + case Intrinsic::experimental_patchpoint_double: return selectPatchpoint(II); } Index: lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -2026,6 +2026,7 @@ break; case Intrinsic::experimental_patchpoint_void: case Intrinsic::experimental_patchpoint_i64: + case Intrinsic::experimental_patchpoint_double: visitPatchpoint(ImmutableCallSite(&I), LandingPad); break; } @@ -5536,7 +5537,8 @@ return nullptr; } case Intrinsic::experimental_patchpoint_void: - case Intrinsic::experimental_patchpoint_i64: { + case Intrinsic::experimental_patchpoint_i64: + case Intrinsic::experimental_patchpoint_double: { visitPatchpoint(ImmutableCallSite(&I), nullptr); return nullptr; } Index: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -1014,6 +1014,7 @@ NumFastIselFailStackMap++; return; case Intrinsic::experimental_patchpoint_void: // fall-through case Intrinsic::experimental_patchpoint_i64: + case Intrinsic::experimental_patchpoint_double: NumFastIselFailPatchPoint++; return; } } Index: lib/IR/Verifier.cpp =================================================================== --- lib/IR/Verifier.cpp +++ lib/IR/Verifier.cpp @@ -2218,7 +2218,8 @@ Assert1(!F->isIntrinsic() || isa(I) || F->getIntrinsicID() == Intrinsic::donothing || F->getIntrinsicID() == Intrinsic::experimental_patchpoint_void || - F->getIntrinsicID() == Intrinsic::experimental_patchpoint_i64, + F->getIntrinsicID() == Intrinsic::experimental_patchpoint_i64 || + F->getIntrinsicID() == Intrinsic::experimental_patchpoint_double, "Cannot invoke an intrinsinc other than" " donothing or patchpoint", &I); Assert1(F->getParent() == M, "Referencing function in another module!", Index: lib/Target/AArch64/AArch64TargetTransformInfo.cpp =================================================================== --- lib/Target/AArch64/AArch64TargetTransformInfo.cpp +++ lib/Target/AArch64/AArch64TargetTransformInfo.cpp @@ -280,6 +280,7 @@ break; case Intrinsic::experimental_patchpoint_void: case Intrinsic::experimental_patchpoint_i64: + case Intrinsic::experimental_patchpoint_double: if ((Idx < 4) || (Imm.getBitWidth() <= 64 && isInt<64>(Imm.getSExtValue()))) return TCC_Free; break; Index: lib/Target/X86/X86TargetTransformInfo.cpp =================================================================== --- lib/Target/X86/X86TargetTransformInfo.cpp +++ lib/Target/X86/X86TargetTransformInfo.cpp @@ -1141,6 +1141,7 @@ break; case Intrinsic::experimental_patchpoint_void: case Intrinsic::experimental_patchpoint_i64: + case Intrinsic::experimental_patchpoint_double: if ((Idx < 4) || (Imm.getBitWidth() <= 64 && isInt<64>(Imm.getSExtValue()))) return TCC_Free; break; Index: test/CodeGen/X86/anyregcc.ll =================================================================== --- test/CodeGen/X86/anyregcc.ll +++ test/CodeGen/X86/anyregcc.ll @@ -11,11 +11,11 @@ ; CHECK-NEXT: .byte 0 ; CHECK-NEXT: .short 0 ; Num Functions -; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 9 ; Num Constants ; CHECK-NEXT: .long 0 ; Num Callsites -; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 9 ; Functions and stack size ; CHECK-NEXT: .quad _test @@ -26,6 +26,8 @@ ; CHECK-NEXT: .quad 24 ; CHECK-NEXT: .quad _property_access3 ; CHECK-NEXT: .quad 24 +; CHECK-NEXT: .quad _property_access_double +; CHECK-NEXT: .quad 8 ; CHECK-NEXT: .quad _anyreg_test1 ; CHECK-NEXT: .quad 56 ; CHECK-NEXT: .quad _anyreg_test2 @@ -132,6 +134,23 @@ ret i64 %ret } +; property access double +; CHECK-LABEL: .long L{{.*}}_property_access_double +; CHECK-NEXT: .short 0 +; 2 locations +; CHECK-NEXT: .short 1 +; Loc 0: Register <-- this is the return register +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 16 +; CHECK-NEXT: .short {{[0-9]+}} +; CHECK-NEXT: .long 0 +define double @property_access_double() nounwind ssp uwtable { +entry: + %f = inttoptr i64 12297829382473034410 to i8* + %ret = call anyregcc double (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.double(i64 1, i32 15, i8* %f, i32 0) + ret double %ret +} + ; anyreg_test1 ; CHECK-LABEL: .long L{{.*}}-_anyreg_test1 ; CHECK-NEXT: .short 0 @@ -466,3 +485,4 @@ declare void @llvm.experimental.patchpoint.void(i64, i32, i8*, i32, ...) declare i64 @llvm.experimental.patchpoint.i64(i64, i32, i8*, i32, ...) +declare double @llvm.experimental.patchpoint.double(i64, i32, i8*, i32, ...) Index: test/CodeGen/X86/patchpoint.ll =================================================================== --- test/CodeGen/X86/patchpoint.ll +++ test/CodeGen/X86/patchpoint.ll @@ -21,6 +21,23 @@ ret i64 %result } +define double @double_patchpoint(double %p1, double %p2, double %p3, double %p4) { +entry: +; CHECK-LABEL: double_patchpoint: +; CHECK: movabsq $-559038736, %r11 +; CHECK-NEXT: callq *%r11 +; CHECK-NEXT: xchgw %ax, %ax +; CHECK: movsd %xmm0, [[SPILL:[^ ]+]] +; CHECK: callq *%r11 +; CHECK-NEXT: xchgw %ax, %ax +; CHECK: movsd [[SPILL]], %xmm0 +; CHECK: ret + %resolveCall2 = inttoptr i64 -559038736 to i8* + %result = tail call double (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.double(i64 2, i32 15, i8* %resolveCall2, i32 4, double %p1, double %p2, double %p3, double %p4) + %result2 = tail call double (i64, i32, i8*, i32, ...)* @llvm.experimental.patchpoint.double(i64 2, i32 15, i8* %resolveCall2, i32 4, double %p1, double %p2, double %p3, double %p4) + ret double %result +} + ; Caller frame metadata with stackmaps. This should not be optimized ; as a leaf function. ; @@ -85,3 +102,4 @@ declare void @llvm.experimental.stackmap(i64, i32, ...) declare void @llvm.experimental.patchpoint.void(i64, i32, i8*, i32, ...) declare i64 @llvm.experimental.patchpoint.i64(i64, i32, i8*, i32, ...) +declare double @llvm.experimental.patchpoint.double(i64, i32, i8*, i32, ...)