@@ -486,6 +486,7 @@ struct IntrinsicLibrary {
486
486
void genRandomInit (llvm::ArrayRef<fir::ExtendedValue>);
487
487
void genRandomNumber (llvm::ArrayRef<fir::ExtendedValue>);
488
488
void genRandomSeed (llvm::ArrayRef<fir::ExtendedValue>);
489
+ fir::ExtendedValue genScan (mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
489
490
mlir::Value genSetExponent (mlir::Type resultType,
490
491
llvm::ArrayRef<mlir::Value> args);
491
492
fir::ExtendedValue genSize (mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
@@ -495,6 +496,7 @@ struct IntrinsicLibrary {
495
496
llvm::ArrayRef<fir::ExtendedValue>);
496
497
fir::ExtendedValue genUbound (mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
497
498
fir::ExtendedValue genUnpack (mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
499
+ fir::ExtendedValue genVerify (mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
498
500
499
501
// / Define the different FIR generators that can be mapped to intrinsic to
500
502
// / generate the related code.
@@ -727,6 +729,13 @@ static constexpr IntrinsicHandler handlers[]{
727
729
&I::genRandomSeed,
728
730
{{{" size" , asBox}, {" put" , asBox}, {" get" , asBox}}},
729
731
/* isElemental=*/ false },
732
+ {" scan" ,
733
+ &I::genScan,
734
+ {{{" string" , asAddr},
735
+ {" set" , asAddr},
736
+ {" back" , asValue, handleDynamicOptional},
737
+ {" kind" , asValue}}},
738
+ /* isElemental=*/ true },
730
739
{" set_exponent" , &I::genSetExponent},
731
740
{" size" ,
732
741
&I::genSize,
@@ -756,6 +765,13 @@ static constexpr IntrinsicHandler handlers[]{
756
765
&I::genUnpack,
757
766
{{{" vector" , asBox}, {" mask" , asBox}, {" field" , asBox}}},
758
767
/* isElemental=*/ false },
768
+ {" verify" ,
769
+ &I::genVerify,
770
+ {{{" string" , asAddr},
771
+ {" set" , asAddr},
772
+ {" back" , asValue, handleDynamicOptional},
773
+ {" kind" , asValue}}},
774
+ /* isElemental=*/ true },
759
775
};
760
776
761
777
static const IntrinsicHandler *findIntrinsicHandler (llvm::StringRef name) {
@@ -2485,6 +2501,83 @@ void IntrinsicLibrary::genRandomSeed(llvm::ArrayRef<fir::ExtendedValue> args) {
2485
2501
Fortran::lower::genRandomSeed (builder, loc, -1 , mlir::Value{});
2486
2502
}
2487
2503
2504
+ // SCAN
2505
+ fir::ExtendedValue
2506
+ IntrinsicLibrary::genScan (mlir::Type resultType,
2507
+ llvm::ArrayRef<fir::ExtendedValue> args) {
2508
+
2509
+ assert (args.size () == 4 );
2510
+
2511
+ if (isAbsent (args[3 ])) {
2512
+ // Kind not specified, so call scan/verify runtime routine that is
2513
+ // specialized on the kind of characters in string.
2514
+
2515
+ // Handle required string base arg
2516
+ mlir::Value stringBase = fir::getBase (args[0 ]);
2517
+
2518
+ // Handle required set string base arg
2519
+ mlir::Value setBase = fir::getBase (args[1 ]);
2520
+
2521
+ // Handle kind argument; it is the kind of character in this case
2522
+ fir::KindTy kind =
2523
+ fir::factory::CharacterExprHelper{builder, loc}.getCharacterKind (
2524
+ stringBase.getType ());
2525
+
2526
+ // Get string length argument
2527
+ mlir::Value stringLen = fir::getLen (args[0 ]);
2528
+
2529
+ // Get set string length argument
2530
+ mlir::Value setLen = fir::getLen (args[1 ]);
2531
+
2532
+ // Handle optional back argument
2533
+ mlir::Value back =
2534
+ isAbsent (args[2 ])
2535
+ ? builder.createIntegerConstant (loc, builder.getI1Type (), 0 )
2536
+ : fir::getBase (args[2 ]);
2537
+
2538
+ return builder.createConvert (loc, resultType,
2539
+ fir::runtime::genScan (builder, loc, kind,
2540
+ stringBase, stringLen,
2541
+ setBase, setLen, back));
2542
+ }
2543
+ // else use the runtime descriptor version of scan/verify
2544
+
2545
+ // Handle optional argument, back
2546
+ auto makeRefThenEmbox = [&](mlir::Value b) {
2547
+ fir::LogicalType logTy = fir::LogicalType::get (
2548
+ builder.getContext (), builder.getKindMap ().defaultLogicalKind ());
2549
+ mlir::Value temp = builder.createTemporary (loc, logTy);
2550
+ mlir::Value castb = builder.createConvert (loc, logTy, b);
2551
+ builder.create <fir::StoreOp>(loc, castb, temp);
2552
+ return builder.createBox (loc, temp);
2553
+ };
2554
+ mlir::Value back = fir::isUnboxedValue (args[2 ])
2555
+ ? makeRefThenEmbox (*args[2 ].getUnboxed ())
2556
+ : builder.create <fir::AbsentOp>(
2557
+ loc, fir::BoxType::get (builder.getI1Type ()));
2558
+
2559
+ // Handle required string argument
2560
+ mlir::Value string = builder.createBox (loc, args[0 ]);
2561
+
2562
+ // Handle required set argument
2563
+ mlir::Value set = builder.createBox (loc, args[1 ]);
2564
+
2565
+ // Handle kind argument
2566
+ mlir::Value kind = fir::getBase (args[3 ]);
2567
+
2568
+ // Create result descriptor
2569
+ fir::MutableBoxValue resultMutableBox =
2570
+ fir::factory::createTempMutableBox (builder, loc, resultType);
2571
+ mlir::Value resultIrBox =
2572
+ fir::factory::getMutableIRBox (builder, loc, resultMutableBox);
2573
+
2574
+ fir::runtime::genScanDescriptor (builder, loc, resultIrBox, string, set, back,
2575
+ kind);
2576
+
2577
+ // Handle cleanup of allocatable result descriptor and return
2578
+ return readAndAddCleanUp (resultMutableBox, resultType, " SCAN" );
2579
+ }
2580
+
2488
2581
// SET_EXPONENT
2489
2582
mlir::Value IntrinsicLibrary::genSetExponent (mlir::Type resultType,
2490
2583
llvm::ArrayRef<mlir::Value> args) {
@@ -2710,6 +2803,83 @@ IntrinsicLibrary::genUnpack(mlir::Type resultType,
2710
2803
" unexpected result for UNPACK" );
2711
2804
}
2712
2805
2806
+ // VERIFY
2807
+ fir::ExtendedValue
2808
+ IntrinsicLibrary::genVerify (mlir::Type resultType,
2809
+ llvm::ArrayRef<fir::ExtendedValue> args) {
2810
+
2811
+ assert (args.size () == 4 );
2812
+
2813
+ if (isAbsent (args[3 ])) {
2814
+ // Kind not specified, so call scan/verify runtime routine that is
2815
+ // specialized on the kind of characters in string.
2816
+
2817
+ // Handle required string base arg
2818
+ mlir::Value stringBase = fir::getBase (args[0 ]);
2819
+
2820
+ // Handle required set string base arg
2821
+ mlir::Value setBase = fir::getBase (args[1 ]);
2822
+
2823
+ // Handle kind argument; it is the kind of character in this case
2824
+ fir::KindTy kind =
2825
+ fir::factory::CharacterExprHelper{builder, loc}.getCharacterKind (
2826
+ stringBase.getType ());
2827
+
2828
+ // Get string length argument
2829
+ mlir::Value stringLen = fir::getLen (args[0 ]);
2830
+
2831
+ // Get set string length argument
2832
+ mlir::Value setLen = fir::getLen (args[1 ]);
2833
+
2834
+ // Handle optional back argument
2835
+ mlir::Value back =
2836
+ isAbsent (args[2 ])
2837
+ ? builder.createIntegerConstant (loc, builder.getI1Type (), 0 )
2838
+ : fir::getBase (args[2 ]);
2839
+
2840
+ return builder.createConvert (
2841
+ loc, resultType,
2842
+ fir::runtime::genVerify (builder, loc, kind, stringBase, stringLen,
2843
+ setBase, setLen, back));
2844
+ }
2845
+ // else use the runtime descriptor version of scan/verify
2846
+
2847
+ // Handle optional argument, back
2848
+ auto makeRefThenEmbox = [&](mlir::Value b) {
2849
+ fir::LogicalType logTy = fir::LogicalType::get (
2850
+ builder.getContext (), builder.getKindMap ().defaultLogicalKind ());
2851
+ mlir::Value temp = builder.createTemporary (loc, logTy);
2852
+ mlir::Value castb = builder.createConvert (loc, logTy, b);
2853
+ builder.create <fir::StoreOp>(loc, castb, temp);
2854
+ return builder.createBox (loc, temp);
2855
+ };
2856
+ mlir::Value back = fir::isUnboxedValue (args[2 ])
2857
+ ? makeRefThenEmbox (*args[2 ].getUnboxed ())
2858
+ : builder.create <fir::AbsentOp>(
2859
+ loc, fir::BoxType::get (builder.getI1Type ()));
2860
+
2861
+ // Handle required string argument
2862
+ mlir::Value string = builder.createBox (loc, args[0 ]);
2863
+
2864
+ // Handle required set argument
2865
+ mlir::Value set = builder.createBox (loc, args[1 ]);
2866
+
2867
+ // Handle kind argument
2868
+ mlir::Value kind = fir::getBase (args[3 ]);
2869
+
2870
+ // Create result descriptor
2871
+ fir::MutableBoxValue resultMutableBox =
2872
+ fir::factory::createTempMutableBox (builder, loc, resultType);
2873
+ mlir::Value resultIrBox =
2874
+ fir::factory::getMutableIRBox (builder, loc, resultMutableBox);
2875
+
2876
+ fir::runtime::genVerifyDescriptor (builder, loc, resultIrBox, string, set,
2877
+ back, kind);
2878
+
2879
+ // Handle cleanup of allocatable result descriptor and return
2880
+ return readAndAddCleanUp (resultMutableBox, resultType, " VERIFY" );
2881
+ }
2882
+
2713
2883
// ===----------------------------------------------------------------------===//
2714
2884
// Argument lowering rules interface
2715
2885
// ===----------------------------------------------------------------------===//
0 commit comments