llvm.org GIT mirror llvm / 921f454
Replace hardcoded intrinsic list with speculatable attribute. No change in which intrinsics should be speculated. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@301995 91177308-0d34-0410-b5e6-96231b3b80d8 Matt Arsenault 3 years ago
12 changed file(s) with 45 addition(s) and 90 deletion(s). Raw diff Collapse all Expand all
403403 // FIXME: Add version of these floating point intrinsics which allow non-default
404404 // rounding modes and FP exception handling.
405405
406 let IntrProperties = [IntrNoMem] in {
406 let IntrProperties = [IntrNoMem, IntrSpeculatable] in {
407407 def int_fma : Intrinsic<[llvm_anyfloat_ty],
408408 [LLVMMatchType<0>, LLVMMatchType<0>,
409409 LLVMMatchType<0>]>;
439439 }
440440
441441 def int_minnum : Intrinsic<[llvm_anyfloat_ty],
442 [LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem, Commutative]
442 [LLVMMatchType<0>, LLVMMatchType<0>],
443 [IntrNoMem, IntrSpeculatable, Commutative]
443444 >;
444445 def int_maxnum : Intrinsic<[llvm_anyfloat_ty],
445 [LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem, Commutative]
446 [LLVMMatchType<0>, LLVMMatchType<0>],
447 [IntrNoMem, IntrSpeculatable, Commutative]
446448 >;
447449
448450 // NOTE: these are internal interfaces.
454456 // Internal interface for object size checking
455457 def int_objectsize : Intrinsic<[llvm_anyint_ty],
456458 [llvm_anyptr_ty, llvm_i1_ty, llvm_i1_ty],
457 [IntrNoMem]>,
459 [IntrNoMem, IntrSpeculatable]>,
458460 GCCBuiltin<"__builtin_object_size">;
459461
460462 //===--------------- Constrained Floating Point Intrinsics ----------------===//
499501 //
500502
501503 // None of these intrinsics accesses memory at all.
502 let IntrProperties = [IntrNoMem] in {
504 let IntrProperties = [IntrNoMem, IntrSpeculatable] in {
503505 def int_bswap: Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>]>;
504506 def int_ctpop: Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>]>;
505507 def int_ctlz : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, llvm_i1_ty]>;
510512 //===------------------------ Debugger Intrinsics -------------------------===//
511513 //
512514
513 // None of these intrinsics accesses memory at all...but that doesn't mean the
514 // optimizers can change them aggressively. Special handling needed in a few
515 // places.
516 let IntrProperties = [IntrNoMem] in {
515 // None of these intrinsics accesses memory at all...but that doesn't
516 // mean the optimizers can change them aggressively. Special handling
517 // needed in a few places. These synthetic intrinsics have no
518 // side-effects and just mark information about their operands.
519 let IntrProperties = [IntrNoMem, IntrSpeculatable] in {
517520 def int_dbg_declare : Intrinsic<[],
518521 [llvm_metadata_ty,
519522 llvm_metadata_ty,
591594 // Expose the carry flag from add operations on two integrals.
592595 def int_sadd_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty],
593596 [LLVMMatchType<0>, LLVMMatchType<0>],
594 [IntrNoMem]>;
597 [IntrNoMem, IntrSpeculatable]>;
595598 def int_uadd_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty],
596599 [LLVMMatchType<0>, LLVMMatchType<0>],
597 [IntrNoMem]>;
600 [IntrNoMem, IntrSpeculatable]>;
598601
599602 def int_ssub_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty],
600603 [LLVMMatchType<0>, LLVMMatchType<0>],
601 [IntrNoMem]>;
604 [IntrNoMem, IntrSpeculatable]>;
602605 def int_usub_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty],
603606 [LLVMMatchType<0>, LLVMMatchType<0>],
604 [IntrNoMem]>;
607 [IntrNoMem, IntrSpeculatable]>;
605608
606609 def int_smul_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty],
607610 [LLVMMatchType<0>, LLVMMatchType<0>],
608 [IntrNoMem]>;
611 [IntrNoMem, IntrSpeculatable]>;
609612 def int_umul_with_overflow : Intrinsic<[llvm_anyint_ty, llvm_i1_ty],
610613 [LLVMMatchType<0>, LLVMMatchType<0>],
611 [IntrNoMem]>;
614 [IntrNoMem, IntrSpeculatable]>;
612615
613616 //===------------------------- Memory Use Markers -------------------------===//
614617 //
632635 // it can be CSE only if memory didn't change between 2 barriers call,
633636 // which is valid.
634637 // The argument also can't be marked with 'returned' attribute, because
635 // it would remove barrier.
638 // it would remove barrier.
636639 def int_invariant_group_barrier : Intrinsic<[llvm_ptr_ty],
637640 [llvm_ptr_ty],
638641 [IntrReadMem, IntrArgMemOnly]>;
33193319 case Instruction::Call: {
33203320 auto *CI = cast(Inst);
33213321 const Function *Callee = CI->getCalledFunction();
3322 if (Callee && Callee->isSpeculatable())
3323 return true;
3324 if (const IntrinsicInst *II = dyn_cast(Inst)) {
3325 switch (II->getIntrinsicID()) {
3326 // These synthetic intrinsics have no side-effects and just mark
3327 // information about their operands.
3328 // FIXME: There are other no-op synthetic instructions that potentially
3329 // should be considered at least *safe* to speculate...
3330 // FIXME: The speculatable attribute should be added to all these
3331 // intrinsics and this case statement should be removed.
3332 case Intrinsic::dbg_declare:
3333 case Intrinsic::dbg_value:
3334 return true;
3335
3336 case Intrinsic::bitreverse:
3337 case Intrinsic::bswap:
3338 case Intrinsic::ctlz:
3339 case Intrinsic::ctpop:
3340 case Intrinsic::cttz:
3341 case Intrinsic::objectsize:
3342 case Intrinsic::sadd_with_overflow:
3343 case Intrinsic::smul_with_overflow:
3344 case Intrinsic::ssub_with_overflow:
3345 case Intrinsic::uadd_with_overflow:
3346 case Intrinsic::umul_with_overflow:
3347 case Intrinsic::usub_with_overflow:
3348 return true;
3349 // These intrinsics are defined to have the same behavior as libm
3350 // functions except for setting errno.
3351 case Intrinsic::sqrt:
3352 case Intrinsic::fma:
3353 case Intrinsic::fmuladd:
3354 return true;
3355 // These intrinsics are defined to have the same behavior as libm
3356 // functions, and the corresponding libm functions never set errno.
3357 case Intrinsic::trunc:
3358 case Intrinsic::copysign:
3359 case Intrinsic::fabs:
3360 case Intrinsic::minnum:
3361 case Intrinsic::maxnum:
3362 return true;
3363 // These intrinsics are defined to have the same behavior as libm
3364 // functions, which never overflow when operating on the IEEE754 types
3365 // that we support, and never set errno otherwise.
3366 case Intrinsic::ceil:
3367 case Intrinsic::floor:
3368 case Intrinsic::nearbyint:
3369 case Intrinsic::rint:
3370 case Intrinsic::round:
3371 return true;
3372 // These intrinsics do not correspond to any libm function, and
3373 // do not set errno.
3374 case Intrinsic::powi:
3375 return true;
3376 // TODO: are convert_{from,to}_fp16 safe?
3377 // TODO: can we list target-specific intrinsics here?
3378 default: break;
3379 }
3380 }
3381 return false; // The called function could have undefined behavior or
3382 // side-effects, even if marked readnone nounwind.
3322
3323 // The called function could have undefined behavior or side-effects, even
3324 // if marked readnone nounwind.
3325 return Callee && Callee->isSpeculatable();
33833326 }
33843327 case Instruction::VAArg:
33853328 case Instruction::Alloca:
888888 Value *Callee = M->getOrInsertFunction(Name, Op->getType(),
889889 Op->getType());
890890 CallInst *CI = B.CreateCall(Callee, Op, Name);
891 CI->setAttributes(Attrs);
891
892 // The incoming attribute set may have come from a speculatable intrinsic, but
893 // is being replaced with a library call which is not allowed to be
894 // speculatable.
895 CI->setAttributes(Attrs.removeAttribute(B.getContext(),
896 AttributeList::FunctionIndex,
897 Attribute::Speculatable));
892898 if (const Function *F = dyn_cast(Callee->stripPointerCasts()))
893899 CI->setCallingConv(F->getCallingConv());
894900
6868 ret void
6969 }
7070
71 ; CHECK: attributes #0 = { nounwind readnone }
71 ; CHECK: attributes #0 = { nounwind readnone speculatable }
7272 ; CHECK: attributes #1 = { noreturn nounwind }
502502 ; CHECK: declare <2 x i64> @llvm.ctpop.v2i64(<2 x i64>) #0
503503 ; CHECK: declare <2 x i64> @llvm.ctlz.v2i64(<2 x i64>, i1) #0
504504 ; CHECK: declare <2 x i64> @llvm.cttz.v2i64(<2 x i64>, i1) #0
505 ; CHECK: attributes #0 = { nounwind readnone }
505 ; CHECK: attributes #0 = { nounwind readnone speculatable }
3838 declare void @llvm.dbg.value(metadata, i64, metadata, metadata) nounwind readnone
3939
4040 ; CHECK: attributes #0 = { nounwind ssp }
41 ; CHECK: attributes #1 = { nounwind readnone }
41 ; CHECK: attributes #1 = { nounwind readnone speculatable }
4242 ; CHECK: attributes #2 = { noinline nounwind ssp }
4343 ; CHECK: attributes [[NUW]] = { nounwind }
4444
283283 define i1 @cttz_knownbits(i32 %arg) {
284284 ; CHECK-LABEL: @cttz_knownbits(
285285 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[ARG:%.*]], 4
286 ; CHECK-NEXT: [[CNT:%.*]] = call i32 @llvm.cttz.i32(i32 [[OR]], i1 true) #0
286 ; CHECK-NEXT: [[CNT:%.*]] = call i32 @llvm.cttz.i32(i32 [[OR]], i1 true)
287287 ; CHECK-NEXT: [[RES:%.*]] = icmp eq i32 [[CNT]], 4
288288 ; CHECK-NEXT: ret i1 [[RES]]
289289 ;
306306 define i1 @ctlz_knownbits(i8 %arg) {
307307 ; CHECK-LABEL: @ctlz_knownbits(
308308 ; CHECK-NEXT: [[OR:%.*]] = or i8 [[ARG:%.*]], 32
309 ; CHECK-NEXT: [[CNT:%.*]] = call i8 @llvm.ctlz.i8(i8 [[OR]], i1 true) #0
309 ; CHECK-NEXT: [[CNT:%.*]] = call i8 @llvm.ctlz.i8(i8 [[OR]], i1 true)
310310 ; CHECK-NEXT: [[RES:%.*]] = icmp eq i8 [[CNT]], 4
311311 ; CHECK-NEXT: ret i1 [[RES]]
312312 ;
55 }
66
77 ; CHECK-LABEL: define double @pow_half(
8 ; CHECK-NEXT: %sqrt = call fast double @sqrt(double %x)
8 ; CHECK-NEXT: %sqrt = call fast double @sqrt(double %x) #1
99 ; CHECK-NEXT: ret double %sqrt
1010
1111 define double @pow_neghalf(double %x) {
1414 }
1515
1616 ; CHECK-LABEL: define double @pow_neghalf(
17 ; CHECK-NEXT: %sqrt = call fast double @sqrt(double %x) #0
17 ; CHECK-NEXT: %sqrt = call fast double @sqrt(double %x) #1
1818 ; CHECK-NEXT: %sqrtrecip = fdiv fast double 1.000000e+00, %sqrt
1919 ; CHECK-NEXT: ret double %sqrtrecip
2020
21 declare double @llvm.pow.f64(double, double)
21 declare double @llvm.pow.f64(double, double) #0
22
23 attributes #0 = { nounwind readnone speculatable }
24 attributes #1 = { nounwind readnone }
2626
2727 define i32 @test2(i32 %x) nounwind {
2828 ; CHECK-LABEL: @test2(
29 ; CHECK-NEXT: [[COUNT:%.*]] = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true) #0
29 ; CHECK-NEXT: [[COUNT:%.*]] = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
3030 ; CHECK-NEXT: [[SUB:%.*]] = xor i32 [[COUNT]], 31
3131 ; CHECK-NEXT: ret i32 [[SUB]]
3232 ;
30483048 !4 = !DIFile(filename: "path/to/file", directory: "/path/to/dir")
30493049 !5 = !{i32 2, !"Debug Info Version", i32 3}
30503050
3051 ; CHECK: attributes #0 = { nounwind readnone }
3051 ; CHECK: attributes #0 = { nounwind readnone speculatable }
30523052 ; CHECK: attributes [[NUW]] = { nounwind }
30533053 ; CHECK: ![[RELEASE]] = !{}
104104 declare void @llvm.dbg.value(metadata, i64, metadata, metadata) nounwind readnone
105105
106106 ; CHECK: attributes #0 = { ssp uwtable }
107 ; CHECK: attributes #1 = { nounwind readnone }
107 ; CHECK: attributes #1 = { nounwind readnone speculatable }
108108 ; CHECK: attributes #2 = { nonlazybind }
109109 ; CHECK: attributes #3 = { noinline ssp uwtable }
110110 ; CHECK: attributes [[NUW]] = { nounwind }
146146 ; CHECK: declare <2 x double> @llvm.pow.v2f64(<2 x double>, <2 x double>) [[ATTR0]]
147147 ; CHECK: declare <2 x double> @llvm.exp2.v2f64(<2 x double>) [[ATTR0]]
148148
149 ; CHECK: attributes [[ATTR0]] = { nounwind readnone }
149 ; CHECK: attributes [[ATTR0]] = { nounwind readnone speculatable }
150150