-
Notifications
You must be signed in to change notification settings - Fork 15.1k
[flang/flang-rt] Adding support of RAND, IRAND and SRAND intrinsics #166780
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
@llvm/pr-subscribers-flang-fir-hlfir Author: Jean-Didier PAILLEUX (JDPailleux) ChangesThis PR adds support of RAND, IRAND and SRAND intrinsics in Flang, which are part of the GNU extension. Full diff: https://github.com/llvm/llvm-project/pull/166780.diff 4 Files Affected:
diff --git a/flang-rt/lib/runtime/extensions.cpp b/flang-rt/lib/runtime/extensions.cpp
index 19e75143705ab..366406d2a71e4 100644
--- a/flang-rt/lib/runtime/extensions.cpp
+++ b/flang-rt/lib/runtime/extensions.cpp
@@ -398,6 +398,29 @@ std::int64_t RTNAME(time)() { return time(nullptr); }
// MCLOCK: returns accumulated CPU time in ticks
std::int32_t FORTRAN_PROCEDURE_NAME(mclock)() { return std::clock(); }
+// IRAND(I)
+int FORTRAN_PROCEDURE_NAME(irand)(int i) {
+ switch (i) {
+ case 0:
+ break;
+ case 1:
+ FORTRAN_PROCEDURE_NAME(srand)(0);
+ break;
+ default:
+ FORTRAN_PROCEDURE_NAME(srand)(i);
+ break;
+ }
+ return rand();
+}
+
+// RAND(I)
+float FORTRAN_PROCEDURE_NAME(rand)(int i) {
+ return (float)(FORTRAN_PROCEDURE_NAME(irand)(i));
+}
+
+// SRAND(SEED)
+void FORTRAN_PROCEDURE_NAME(srand)(int seed) { srand(seed); }
+
// Extension procedures related to I/O
namespace io {
diff --git a/flang/docs/Intrinsics.md b/flang/docs/Intrinsics.md
index bfda5f3253a68..af20892edd201 100644
--- a/flang/docs/Intrinsics.md
+++ b/flang/docs/Intrinsics.md
@@ -1379,3 +1379,46 @@ This is prefixed by `STRING`, a colon and a space.
- **Standard:** GNU extension
- **Class:** subroutine
- **Syntax:** `CALL PERROR(STRING)`
+
+
+### Non-Standard Intrinsics: SRAND
+
+#### Description
+`SAND` reinitializes the pseudo-random number generator called by `RAND` and `IRAND`.
+The new seed used by the generator is specified by the required argument `SEED`.
+
+#### Usage and Info
+
+- **Standard:** GNU extension
+- **Class:** Subroutine
+- **Syntax:** `CALL SRAND(SEED)`
+
+### Non-Standard Intrinsics: IRAND
+
+#### Description
+`IRAND(FLAG)` returns a pseudo-random number from a uniform distribution between 0 and 1.
+If `FLAG` is 0, the next number in the current sequence is returned;
+If `FLAG` is 1, the generator is restarted by `CALL SRAND(0)`;
+If `FLAG` has any other value, it is used as a new seed with `SRAND`.
+The return value is of `INTEGER` type of kind 4.
+
+#### Usage and Info
+
+- **Standard:** GNU extension
+- **Class:** function
+- **Syntax:** `RESULT = IRAND(I)`
+
+### Non-Standard Intrinsics: RAND
+
+#### Description
+`RAND(FLAG)` returns a pseudo-random number from a uniform distribution between 0 and 1.
+If `FLAG` is 0, the next number in the current sequence is returned;
+If `FLAG` is 1, the generator is restarted by `CALL SRAND(0)`;
+If `FLAG` has any other value, it is used as a new seed with `SRAND`.
+The return value is of `REAL` type with the default kind.
+
+#### Usage and Info
+
+- **Standard:** GNU extension
+- **Class:** function
+- **Syntax:** `RESULT = RAND(I)`
diff --git a/flang/include/flang/Runtime/extensions.h b/flang/include/flang/Runtime/extensions.h
index 9fd3e118a0f22..73a458b26e2d7 100644
--- a/flang/include/flang/Runtime/extensions.h
+++ b/flang/include/flang/Runtime/extensions.h
@@ -101,5 +101,14 @@ int FORTRAN_PROCEDURE_NAME(mclock)();
float FORTRAN_PROCEDURE_NAME(secnds)(float *refTime);
float RTNAME(Secnds)(float *refTime, const char *sourceFile, int line);
+// GNU extension function IRAND(I)
+int FORTRAN_PROCEDURE_NAME(irand)(int i = 0);
+
+// GNU extension function RAND(I)
+float FORTRAN_PROCEDURE_NAME(rand)(int i = 0);
+
+// GNU extension subroutine SRAND(SEED)
+void FORTRAN_PROCEDURE_NAME(srand)(int seed);
+
} // extern "C"
#endif // FORTRAN_RUNTIME_EXTENSIONS_H_
diff --git a/flang/test/Lower/Intrinsics/rand.f90 b/flang/test/Lower/Intrinsics/rand.f90
new file mode 100644
index 0000000000000..488242fb9180d
--- /dev/null
+++ b/flang/test/Lower/Intrinsics/rand.f90
@@ -0,0 +1,41 @@
+! RUN: bbc -emit-hlfir %s -o - | FileCheck --check-prefixes=CHECK %s
+! RUN: %flang_fc1 -emit-hlfir %s -o - | FileCheck --check-prefixes=CHECK %s
+
+! CHECK-LABEL: func @_QPtest_srand(
+subroutine test_srand()
+ integer :: seed = 0
+ call srand(seed)
+ ! CHECK: %[[VAL_0:.*]] = fir.address_of(@_QFtest_srandEseed) : !fir.ref<i32>
+ ! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "_QFtest_srandEseed"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ ! CHECK: fir.call @_QPsrand(%[[VAL_1]]#0) fastmath<contract> : (!fir.ref<i32>) -> ()
+ ! CHECK: return
+end subroutine test_srand
+
+! CHECK-LABEL: func @_QPtest_irand(
+subroutine test_irand()
+ integer :: seed = 0
+ integer :: result
+ result = irand(seed)
+ ! CHECK: %[[VAL_0:.*]] = fir.alloca i32 {bindc_name = "result", uniq_name = "_QFtest_irandEresult"}
+ ! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "_QFtest_irandEresult"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ ! CHECK: %[[VAL_2:.*]] = fir.address_of(@_QFtest_irandEseed) : !fir.ref<i32>
+ ! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_2]] {uniq_name = "_QFtest_irandEseed"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ ! CHECK: %[[VAL_4:.*]] = fir.call @_QPirand(%[[VAL_3]]#0) fastmath<contract> : (!fir.ref<i32>) -> i32
+ ! CHECK: hlfir.assign %[[VAL_4]] to %[[VAL_1]]#0 : i32, !fir.ref<i32>
+ ! CHECK: return
+end subroutine test_irand
+
+! CHECK-LABEL: func @_QPtest_rand(
+subroutine test_rand()
+ integer :: seed = 0
+ real :: result
+ result = rand(seed)
+ ! CHECK: %[[VAL_0:.*]] = fir.alloca f32 {bindc_name = "result", uniq_name = "_QFtest_randEresult"}
+ ! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "_QFtest_randEresult"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
+ ! CHECK: %[[VAL_2:.*]] = fir.address_of(@_QFtest_randEseed) : !fir.ref<i32>
+ ! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_2]] {uniq_name = "_QFtest_randEseed"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+ ! CHECK: %[[VAL_4:.*]] = fir.call @_QPrand(%[[VAL_3]]#0) fastmath<contract> : (!fir.ref<i32>) -> f32
+ ! CHECK: hlfir.assign %[[VAL_4]] to %[[VAL_1]]#0 : f32, !fir.ref<f32>
+ ! CHECK: return
+end subroutine test_rand
+
|
| ### Non-Standard Intrinsics: SRAND | ||
|
|
||
| #### Description | ||
| `SAND` reinitializes the pseudo-random number generator called by `RAND` and `IRAND`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo, should be SRAND
This PR adds support of RAND, IRAND and SRAND intrinsics in Flang, which are part of the GNU extension.
These intrinsics are used in the following benchmark: floatingspeed