@@ -379,10 +379,10 @@ static bool compareFnAttributes(const CodeGenIntrinsic *L,
379379 return TieL < TieR;
380380
381381 // Try to order by readonly/readnone attribute.
382- uint32_t LK = L->ME .toIntValue ();
383- uint32_t RK = R->ME .toIntValue ();
384- if (LK != RK )
385- return LK > RK ;
382+ uint32_t LME = L->ME .toIntValue ();
383+ uint32_t RME = R->ME .toIntValue ();
384+ if (LME != RME )
385+ return LME > RME ;
386386
387387 return Default;
388388}
@@ -404,6 +404,54 @@ struct AttributeComparator {
404404};
405405} // End anonymous namespace
406406
407+ // / Returns the effective MemoryEffects for intrinsic \p Int.
408+ static MemoryEffects getEffectiveME (const CodeGenIntrinsic &Int) {
409+ MemoryEffects ME = Int.ME ;
410+ // TODO: IntrHasSideEffects should affect not only readnone intrinsics.
411+ if (ME.doesNotAccessMemory () && Int.hasSideEffects )
412+ ME = MemoryEffects::unknown ();
413+ return ME;
414+ }
415+
416+ // / Returns true if \p Int has a non-empty set of function attributes. Note that
417+ // / NoUnwind = !canThrow, so we need to negate it's sense to test if the
418+ // intrinsic has NoUnwind attribute.
419+ static bool hasFnAttributes (const CodeGenIntrinsic &Int) {
420+ return !Int.canThrow || Int.isNoReturn || Int.isNoCallback || Int.isNoSync ||
421+ Int.isNoFree || Int.isWillReturn || Int.isCold || Int.isNoDuplicate ||
422+ Int.isNoMerge || Int.isConvergent || Int.isSpeculatable ||
423+ Int.isStrictFP || getEffectiveME (Int) != MemoryEffects::unknown ();
424+ }
425+
426+ // / Returns the name of the IR enum for argument attribute kind \p Kind.
427+ static StringRef getArgAttrEnumName (CodeGenIntrinsic::ArgAttrKind Kind) {
428+ switch (Kind) {
429+ case CodeGenIntrinsic::NoCapture:
430+ return " NoCapture" ;
431+ case CodeGenIntrinsic::NoAlias:
432+ return " NoAlias" ;
433+ case CodeGenIntrinsic::NoUndef:
434+ return " NoUndef" ;
435+ case CodeGenIntrinsic::NonNull:
436+ return " NonNull" ;
437+ case CodeGenIntrinsic::Returned:
438+ return " Returned" ;
439+ case CodeGenIntrinsic::ReadOnly:
440+ return " ReadOnly" ;
441+ case CodeGenIntrinsic::WriteOnly:
442+ return " WriteOnly" ;
443+ case CodeGenIntrinsic::ReadNone:
444+ return " ReadNone" ;
445+ case CodeGenIntrinsic::ImmArg:
446+ return " ImmArg" ;
447+ case CodeGenIntrinsic::Alignment:
448+ return " Alignment" ;
449+ case CodeGenIntrinsic::Dereferenceable:
450+ return " Dereferenceable" ;
451+ }
452+ llvm_unreachable (" Unknown CodeGenIntrinsic::ArgAttrKind enum" );
453+ }
454+
407455// / EmitAttributes - This emits the Intrinsic::getAttributes method.
408456void IntrinsicEmitter::EmitAttributes (const CodeGenIntrinsicTable &Ints,
409457 raw_ostream &OS) {
@@ -425,42 +473,14 @@ static AttributeSet getIntrinsicArgAttributeSet(LLVMContext &C, unsigned ID) {
425473 continue ;
426474
427475 assert (is_sorted (Attrs) && " Argument attributes are not sorted" );
428- auto getAttrEnumName =
429- [](CodeGenIntrinsic::ArgAttrKind Kind) -> StringRef {
430- switch (Kind) {
431- case CodeGenIntrinsic::NoCapture:
432- return " NoCapture" ;
433- case CodeGenIntrinsic::NoAlias:
434- return " NoAlias" ;
435- case CodeGenIntrinsic::NoUndef:
436- return " NoUndef" ;
437- case CodeGenIntrinsic::NonNull:
438- return " NonNull" ;
439- case CodeGenIntrinsic::Returned:
440- return " Returned" ;
441- case CodeGenIntrinsic::ReadOnly:
442- return " ReadOnly" ;
443- case CodeGenIntrinsic::WriteOnly:
444- return " WriteOnly" ;
445- case CodeGenIntrinsic::ReadNone:
446- return " ReadNone" ;
447- case CodeGenIntrinsic::ImmArg:
448- return " ImmArg" ;
449- case CodeGenIntrinsic::Alignment:
450- return " Alignment" ;
451- case CodeGenIntrinsic::Dereferenceable:
452- return " Dereferenceable" ;
453- }
454- llvm_unreachable (" Unknown CodeGenIntrinsic::ArgAttrKind enum" );
455- };
456476
457477 OS << formatv (R"(
458478 case {0}:
459479 return AttributeSet::get(C, {{
460480)" ,
461481 ID);
462482 for (const CodeGenIntrinsic::ArgAttribute &Attr : Attrs) {
463- StringRef AttrName = getAttrEnumName (Attr.Kind );
483+ StringRef AttrName = getArgAttrEnumName (Attr.Kind );
464484 if (Attr.Kind == CodeGenIntrinsic::Alignment ||
465485 Attr.Kind == CodeGenIntrinsic::Dereferenceable)
466486 OS << formatv (" Attribute::get(C, Attribute::{0}, {1}),\n " ,
@@ -473,7 +493,8 @@ static AttributeSet getIntrinsicArgAttributeSet(LLVMContext &C, unsigned ID) {
473493 }
474494 OS << R"(
475495 }
476- } // getIntrinsicArgAttributeSet)" ;
496+ } // getIntrinsicArgAttributeSet
497+ )" ;
477498
478499 // Compute unique function attribute sets.
479500 std::map<const CodeGenIntrinsic *, unsigned , FnAttributeComparator>
@@ -482,9 +503,12 @@ static AttributeSet getIntrinsicArgAttributeSet(LLVMContext &C, unsigned ID) {
482503static AttributeSet getIntrinsicFnAttributeSet(LLVMContext &C, unsigned ID) {
483504 switch (ID) {
484505 default: llvm_unreachable("Invalid attribute set number");)" ;
485- for (const CodeGenIntrinsic &Intrinsic : Ints) {
506+
507+ for (const CodeGenIntrinsic &Int : Ints) {
508+ if (!hasFnAttributes (Int))
509+ continue ;
486510 unsigned ID = UniqFnAttributes.size ();
487- if (!UniqFnAttributes.try_emplace (&Intrinsic , ID).second )
511+ if (!UniqFnAttributes.try_emplace (&Int , ID).second )
488512 continue ;
489513 OS << formatv (R"(
490514 case {0}:
@@ -494,44 +518,42 @@ static AttributeSet getIntrinsicFnAttributeSet(LLVMContext &C, unsigned ID) {
494518 auto addAttribute = [&OS](StringRef Attr) {
495519 OS << formatv (" Attribute::get(C, Attribute::{0}),\n " , Attr);
496520 };
497- if (!Intrinsic .canThrow )
521+ if (!Int .canThrow )
498522 addAttribute (" NoUnwind" );
499- if (Intrinsic .isNoReturn )
523+ if (Int .isNoReturn )
500524 addAttribute (" NoReturn" );
501- if (Intrinsic .isNoCallback )
525+ if (Int .isNoCallback )
502526 addAttribute (" NoCallback" );
503- if (Intrinsic .isNoSync )
527+ if (Int .isNoSync )
504528 addAttribute (" NoSync" );
505- if (Intrinsic .isNoFree )
529+ if (Int .isNoFree )
506530 addAttribute (" NoFree" );
507- if (Intrinsic .isWillReturn )
531+ if (Int .isWillReturn )
508532 addAttribute (" WillReturn" );
509- if (Intrinsic .isCold )
533+ if (Int .isCold )
510534 addAttribute (" Cold" );
511- if (Intrinsic .isNoDuplicate )
535+ if (Int .isNoDuplicate )
512536 addAttribute (" NoDuplicate" );
513- if (Intrinsic .isNoMerge )
537+ if (Int .isNoMerge )
514538 addAttribute (" NoMerge" );
515- if (Intrinsic .isConvergent )
539+ if (Int .isConvergent )
516540 addAttribute (" Convergent" );
517- if (Intrinsic .isSpeculatable )
541+ if (Int .isSpeculatable )
518542 addAttribute (" Speculatable" );
519- if (Intrinsic .isStrictFP )
543+ if (Int .isStrictFP )
520544 addAttribute (" StrictFP" );
521545
522- MemoryEffects ME = Intrinsic.ME ;
523- // TODO: IntrHasSideEffects should affect not only readnone intrinsics.
524- if (ME.doesNotAccessMemory () && Intrinsic.hasSideEffects )
525- ME = MemoryEffects::unknown ();
546+ const MemoryEffects ME = getEffectiveME (Int);
526547 if (ME != MemoryEffects::unknown ()) {
527548 OS << formatv (" // {0}\n " , ME);
528549 OS << formatv (" Attribute::getWithMemoryEffects(C, "
529550 " MemoryEffects::createFromIntValue({0})),\n " ,
530551 ME.toIntValue ());
531552 }
532- OS << " });\n " ;
553+ OS << " });" ;
554+ }
555+ OS << R"(
533556 }
534- OS << R"( }
535557} // getIntrinsicFnAttributeSet
536558
537559AttributeList Intrinsic::getAttributes(LLVMContext &C, ID id) {
@@ -586,11 +608,7 @@ AttributeList Intrinsic::getAttributes(LLVMContext &C, ID id) {
586608 NumAttrs++, AttrIdx, ArgAttrID);
587609 }
588610
589- if (!Int.canThrow ||
590- (Int.ME != MemoryEffects::unknown () && !Int.hasSideEffects ) ||
591- Int.isNoReturn || Int.isNoCallback || Int.isNoSync || Int.isNoFree ||
592- Int.isWillReturn || Int.isCold || Int.isNoDuplicate || Int.isNoMerge ||
593- Int.isConvergent || Int.isSpeculatable || Int.isStrictFP ) {
611+ if (hasFnAttributes (Int)) {
594612 unsigned FnAttrID = UniqFnAttributes.find (&Int)->second ;
595613 OS << formatv (" AS[{0}] = {{AttributeList::FunctionIndex, "
596614 " getIntrinsicFnAttributeSet(C, {1})};\n " ,
0 commit comments