518 lines · plain
1! Note: character comparison is different: at -O0, flang-rt function is called,2! at -O1, inline character comparison is used.3! RUN: %flang_fc1 -emit-fir -O0 -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-O04! RUN: %flang_fc1 -emit-fir -O1 -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-O15 6 !CHECK-LABEL: sinteger7 function sinteger(n)8 integer sinteger9 nn = -8810 ! CHECK-DAG: fir.select_case {{.*}} : i3211 ! CHECK-SAME: upper, %c{{[0-9]+}}_i32,12 ! CHECK-SAME: point, %c{{[0-9]+}}_i32,13 ! CHECK-SAME: #fir.point, %c{{[0-9]+}}_i32,14 ! CHECK-SAME: #fir.interval, %c{{[0-9]+}}_i32, %c{{[0-9]+}}_i32,15 ! CHECK-SAME: #fir.point, %c{{[0-9]+}}_i32,16 ! CHECK-SAME: #fir.point, %c{{[0-9]+}}_i32,17 ! CHECK-SAME: #fir.interval, %c{{[0-9]+}}_i32, %c{{[0-9]+}}_i32,18 ! CHECK-SAME: #fir.lower, %c{{[0-9]+}}_i32,19 ! CHECK-SAME: unit20 select case(n)21 case (:1)22 nn = 123 case (2)24 nn = 225 case default26 nn = 027 case (3)28 nn = 329 case (4:5+1-1)30 nn = 431 case (6)32 nn = 633 case (7,8:15,21:)34 nn = 735 end select36 sinteger = nn37 end38 39 ! CHECK-LABEL: slogical40 subroutine slogical(L)41 logical :: L42 n1 = 043 n2 = 044 n3 = 045 n4 = 046 n5 = 047 n6 = 048 n7 = 049 n8 = 050 51 select case (L)52 end select53 54 select case (L)55 ! CHECK: arith.cmpi eq, %{{[0-9]+}}, %false56 ! CHECK: cf.cond_br57 case (.false.)58 n2 = 159 end select60 61 select case (L)62 ! CHECK: cf.cond_br63 case (.true.)64 n3 = 265 end select66 67 select case (L)68 case default69 n4 = 370 end select71 72 select case (L)73 ! CHECK: arith.cmpi eq, %{{[0-9]+}}, %false74 ! CHECK: cf.cond_br75 case (.false.)76 n5 = 177 ! CHECK: cf.cond_br78 case (.true.)79 n5 = 280 end select81 82 select case (L)83 ! CHECK: arith.cmpi eq, %{{[0-9]+}}, %false84 ! CHECK: cf.cond_br85 case (.false.)86 n6 = 187 case default88 n6 = 389 end select90 91 select case (L)92 ! CHECK: cf.cond_br93 case (.true.)94 n7 = 295 case default96 n7 = 397 end select98 99 select case (L)100 ! CHECK: arith.cmpi eq, %{{[0-9]+}}, %false101 ! CHECK: cf.cond_br102 case (.false.)103 n8 = 1104 ! CHECK: cf.cond_br105 case (.true.)106 n8 = 2107 ! CHECK-NOT: 888108 case default ! dead109 n8 = 888110 end select111 112 print*, n1, n2, n3, n4, n5, n6, n7, n8113 end114 115 ! CHECK-LABEL: scharacter116 subroutine scharacter(c)117 character(*) :: c118 nn = 0119 select case (c)120 case default121 nn = -1122 ! NOTE: common pattern of character comparison: at -O0, runtime function123 ! is called, followed by comparison of i32 values. At -O1 and above, 124 ! inline comparison code is done using loops. The comparison code ends125 ! with comparison of i8 values. At either -O0 or -O1, the comparison126 ! ends with a conditional branch. This comparison pattern is used127 ! throughout this file.128 !129 ! <= 'd'130 ! CHECK-O0: CharacterCompareScalar1131 ! CHECK-O0-NEXT: arith.cmpi sle, %{{[0-9]+}}, %c{{[0-9]+}}_i32 : i32132 ! CHECK-O1: fir.do_loop {{.*}} -> (i8) {133 ! CHECK-O1: arith.cmpi sle, %{{[0-9]+}}, %c{{[0-9]+}}_i8 : i8134 ! CHECK-NEXT: cf.cond_br135 case (:'d')136 nn = 10137 ! 'ff' <= ... <= 'ffff'138 ! CHECK-O0: CharacterCompareScalar1139 ! CHECK-O0-NEXT: arith.cmpi sge, %{{[0-9]+}}, %c{{[0-9]+}}_i32 : i32140 ! CHECK-O1: fir.do_loop {{.*}} -> (i8) {141 ! CHECK-O1: arith.cmpi sge, %{{[0-9]+}}, %c{{[0-9]+}}_i8 : i8142 ! CHECK-NEXT: cf.cond_br143 ! CHECK-O0: CharacterCompareScalar1144 ! CHECK-O0-NEXT: arith.cmpi sle, %{{[0-9]+}}, %c{{[0-9]+}}_i32 : i32145 ! CHECK-O1: fir.do_loop {{.*}} -> (i8) {146 ! CHECK-O1: arith.cmpi sle, %{{[0-9]+}}, %c{{[0-9]+}}_i8 : i8147 ! CHECK-NEXT: cf.cond_br148 case ('ff':'ffff')149 nn = 20150 ! == 'm'151 ! CHECK-O0: CharacterCompareScalar1152 ! CHECK-O0-NEXT: arith.cmpi eq, %{{[0-9]+}}, %c{{[0-9]+}}_i32 : i32153 ! CHECK-O1: fir.do_loop {{.*}} -> (i8) {154 ! CHECK-O1: arith.cmpi eq, %{{[0-9]+}}, %c{{[0-9]+}}_i8 : i8155 ! CHECK-NEXT: cf.cond_br156 case ('m')157 nn = 30158 ! == 'qq'159 ! CHECK-O0: CharacterCompareScalar1160 ! CHECK-O0-NEXT: arith.cmpi eq, %{{[0-9]+}}, %c{{[0-9]+}}_i32 : i32161 ! CHECK-O1: fir.do_loop {{.*}} -> (i8) {162 ! CHECK-O1: arith.cmpi eq, %{{[0-9]+}}, %c{{[0-9]+}}_i8 : i8163 ! CHECK-NEXT: cf.cond_br164 case ('qq')165 nn = 40166 ! >= 'x'167 ! CHECK-O0: CharacterCompareScalar1168 ! CHECK-O0-NEXT: arith.cmpi sge, %{{[0-9]+}}, %c{{[0-9]+}}_i32 : i32169 ! CHECK-O1: fir.do_loop {{.*}} -> (i8) {170 ! CHECK-O1: arith.cmpi sge, %{{[0-9]+}}, %c{{[0-9]+}}_i8 : i8171 ! CHECK-NEXT: cf.cond_br172 case ('x':)173 nn = 50174 end select175 print*, nn176 end177 178 ! CHECK-LABEL: func.func @_QPscharacter1179 subroutine scharacter1(s)180 character(len=3) :: s181 n = 0182 183 ! CHECK: %[[STR00:[0-9]+]] = fir.declare {{.*}} uniq_name = "_QQclX3030"}184 ! CHECK: %[[STR00_CONV:[0-9]+]] = fir.convert %[[STR00]]185 186 ! CHECK-O0: fir.call @_FortranACharacterCompareScalar1({{.*}}, %[[STR00_CONV]]187 ! CHECK-O0-NEXT: arith.cmpi sge, {{.*}}, %c0_i32 : i32188 ! CHECK-O1: fir.do_loop {{.*}} -> (i8) {189 ! CHECK-O1: arith.cmpi sge, %{{[0-9]+}}, %c{{[0-9]+}}_i8 : i8190 ! CHECK-NEXT: cf.cond_br191 if (lge(s,'00')) then192 193 ! CHECK: fir.call @_FortranATrim194 195 ! All the strings in SELECT CASE196 ! CHECK: %[[STR11:[0-9]+]] = fir.declare {{.*}} uniq_name = "_QQclX3131"}197 ! CHECK: %[[STR22:[0-9]+]] = fir.declare {{.*}} uniq_name = "_QQclX3232"}198 ! CHECK: %[[STR33:[0-9]+]] = fir.declare {{.*}} uniq_name = "_QQclX3333"}199 ! CHECK: %[[STR44:[0-9]+]] = fir.declare {{.*}} uniq_name = "_QQclX3434"}200 ! CHECK: %[[STR55:[0-9]+]] = fir.declare {{.*}} uniq_name = "_QQclX3535"}201 ! CHECK: %[[STR66:[0-9]+]] = fir.declare {{.*}} uniq_name = "_QQclX3636"}202 ! CHECK: %[[STR77:[0-9]+]] = fir.declare {{.*}} uniq_name = "_QQclX3737"}203 ! CHECK: %[[STR88:[0-9]+]] = fir.declare {{.*}} uniq_name = "_QQclX3838"}204 205 ! == '11'206 ! CHECK-O0: %[[STR11_CONV:[0-9]+]] = fir.convert %[[STR11]]207 ! CHECK-O0: fir.call @_FortranACharacterCompareScalar1({{.*}}, %[[STR11_CONV]]208 ! CHECK-O0-NEXT: arith.cmpi eq,{{.*}}, %c0_i32 : i32209 ! CHECK-O1: fir.do_loop {{.*}} -> (i8) {210 ! CHECK-O1: arith.cmpi eq, %{{[0-9]+}}, %c{{[0-9]+}}_i8 : i8211 ! CHECK-NEXT: cf.cond_br212 select case(trim(s))213 case('11')214 n = 1215 216 case default217 continue218 219 ! == '22'220 ! CHECK-O0: %[[STR22_CONV:[0-9]+]] = fir.convert %[[STR22]]221 ! CHECK-O0: fir.call @_FortranACharacterCompareScalar1({{.*}}, %[[STR22_CONV]]222 ! CHECK-O0-NEXT: arith.cmpi eq,{{.*}}, %c0_i32 : i32223 ! CHECK-O1: fir.do_loop {{.*}} -> (i8) {224 ! CHECK-O1: arith.cmpi eq, %{{[0-9]+}}, %c{{[0-9]+}}_i8 : i8225 ! CHECK-NEXT: cf.cond_br226 case('22')227 n = 2228 229 ! == '33'230 ! CHECK-O0: %[[STR33_CONV:[0-9]+]] = fir.convert %[[STR33]]231 ! CHECK-O0: fir.call @_FortranACharacterCompareScalar1({{.*}}, %[[STR33_CONV]]232 ! CHECK-O0-NEXT: arith.cmpi eq,{{.*}}, %c0_i32 : i32233 ! CHECK-O1: fir.do_loop {{.*}} -> (i8) {234 ! CHECK-O1: arith.cmpi eq, %{{[0-9]+}}, %c{{[0-9]+}}_i8 : i8235 ! CHECK-NEXT: cf.cond_br236 case('33')237 n = 3238 239 ! >= '44'240 ! CHECK-O0: %[[STR44_CONV:[0-9]+]] = fir.convert %[[STR44]]241 ! CHECK-O0: fir.call @_FortranACharacterCompareScalar1({{.*}}, %[[STR44_CONV]]242 ! CHECK-O0-NEXT: arith.cmpi sge,{{.*}}, %c0_i32 : i32243 ! CHECK-O1: fir.do_loop {{.*}} -> (i8) {244 ! CHECK-O1: arith.cmpi sge, %{{[0-9]+}}, %c{{[0-9]+}}_i8 : i8245 ! CHECK-NEXT: cf.cond_br246 ! <= '55'247 ! CHECK-O0: %[[STR55_CONV:[0-9]+]] = fir.convert %[[STR55]]248 ! CHECK-O0: fir.call @_FortranACharacterCompareScalar1({{.*}}, %[[STR55_CONV]]249 ! CHECK-O0-NEXT: arith.cmpi sle,{{.*}}, %c0_i32 : i32250 ! CHECK-O1: fir.do_loop {{.*}} -> (i8) {251 ! CHECK-O1: arith.cmpi sle, %{{[0-9]+}}, %c{{[0-9]+}}_i8 : i8252 ! CHECK-NEXT: cf.cond_br253 ! >= '66'254 ! CHECK-O0: %[[STR66_CONV:[0-9]+]] = fir.convert %[[STR66]]255 ! CHECK-O0: fir.call @_FortranACharacterCompareScalar1({{.*}}, %[[STR66_CONV]]256 ! CHECK-O0-NEXT: arith.cmpi sge,{{.*}}, %c0_i32 : i32257 ! CHECK-O1: fir.do_loop {{.*}} -> (i8) {258 ! CHECK-O1: arith.cmpi sge, %{{[0-9]+}}, %c{{[0-9]+}}_i8 : i8259 ! CHECK-NEXT: cf.cond_br260 ! <= '77'261 ! CHECK-O0: %[[STR77_CONV:[0-9]+]] = fir.convert %[[STR77]]262 ! CHECK-O0: fir.call @_FortranACharacterCompareScalar1({{.*}}, %[[STR77_CONV]]263 ! CHECK-O0-NEXT: arith.cmpi sle,{{.*}}, %c0_i32 : i32264 ! CHECK-O1: fir.do_loop {{.*}} -> (i8) {265 ! CHECK-O1: arith.cmpi sle, %{{[0-9]+}}, %c{{[0-9]+}}_i8 : i8266 ! CHECK-NEXT: cf.cond_br267 ! >= '88'268 ! CHECK-O0: %[[STR88_CONV:[0-9]+]] = fir.convert %[[STR88]]269 ! CHECK-O0: fir.call @_FortranACharacterCompareScalar1({{.*}}, %[[STR88_CONV]]270 ! CHECK-O0-NEXT: arith.cmpi sge,{{.*}}, %c0_i32 : i32271 ! CHECK-O1: fir.do_loop {{.*}} -> (i8) {272 ! CHECK-O1: arith.cmpi sge, %{{[0-9]+}}, %c{{[0-9]+}}_i8 : i8273 ! CHECK-NEXT: cf.cond_br274 case('44':'55','66':'77','88':)275 n = 4276 end select277 end if278 print*, n279 end subroutine280 281 ! CHECK-LABEL: func @_QPscharacter2282 subroutine scharacter2(s)283 character(len=3) :: s284 ! CHECK: %[[N:[0-9]+]] = fir.declare {{.*}} {uniq_name = "_QFscharacter2En"}285 ! CHECK: fir.store %c-10_i32 to %[[N]] : !fir.ref<i32>286 n = -10287 ! CHECK: fir.call @_FortranATrim(288 select case(trim(s))289 case default290 ! CHECK: fir.store %c9_i32 to %[[N]] : !fir.ref<i32>291 n = 9292 end select293 294 ! CHECK: fir.call @_FortranAioBeginExternalListOutput(295 print*, n296 297 ! CHECK: fir.store %c-2_i32 to %[[N]] : !fir.ref<i32>298 n = -2299 300 ! CHECK: fir.call @_FortranATrim(301 select case(trim(s))302 end select303 ! CHECK: fir.call @_FortranAioBeginExternalListOutput(304 print*, n305 end subroutine306 307 ! CHECK-LABEL: func @_QPsempty308 ! empty select case blocks309 subroutine sempty(n)310 !CHECK: fir.select_case {{.*}} : i32 [#fir.point, %c1_i32, ^bb1, #fir.point, %c2_i32, ^bb2, unit, ^bb3]311 select case (n)312 case (1)313 !CHECK: ^bb1:314 !CHECK: fir.call @_FortranAioBeginExternalListOutput(315 !CHECK: cf.br ^bb4316 print*, n, 'i:case 1'317 case (2)318 !CHECK: ^bb2:319 !CHECK-NEXT: cf.br ^bb4320 ! (empty) print*, n, 'i:case 2'321 case default322 print*, n, 'i:case default'323 end select324 select case (char(ichar('0')+n))325 ! == '1'326 ! CHECK-O0: fir.call @_FortranACharacterCompareScalar1(327 ! CHECK-O0-NEXT: arith.cmpi eq, {{.*}}, %c0_i32 : i32328 ! CHECK-O1: fir.do_loop {{.*}} -> (i8) {329 ! CHECK-O1: arith.cmpi eq, %{{[0-9]+}}, %c{{[0-9]+}}_i8 : i8330 ! CHECK-NEXT: cf.cond_br331 case ('1')332 print*, n, 'c:case 1'333 case ('2')334 ! == '2'335 ! CHECK-O0: fir.call @_FortranACharacterCompareScalar1(336 ! CHECK-O0-NEXT: arith.cmpi eq, {{.*}}, %c0_i32 : i32337 ! CHECK-O1: fir.do_loop {{.*}} -> (i8) {338 ! CHECK-O1: arith.cmpi eq, %{{[0-9]+}}, %c{{[0-9]+}}_i8 : i8339 ! CHECK-NEXT: cf.cond_br340 ! (empty) print*, n, 'c:case 2'341 case default342 print*, n, 'c:case default'343 end select344 ! CHECK: return345 end subroutine346 347 ! CHECK-LABEL: func @_QPsgoto348 ! select case with goto exit349 subroutine sgoto350 n = 0351 ! CHECK: cf.cond_br352 do i=1,8353 ! CHECK: fir.select_case %8 : i32 [#fir.upper, %c2_i32, ^bb{{.*}}, #fir.lower, %c5_i32, ^bb{{.*}}, unit, ^bb{{.*}}]354 select case(i)355 case (:2)356 ! CHECK-DAG: arith.muli {{.*}}, %c10_i32 : i32357 n = i * 10358 case (5:)359 ! CHECK-DAG: arith.muli {{.*}}, %c1000_i32 : i32360 n = i * 1000361 ! CHECK-DAG: arith.cmpi sle, {{.*}}, %c6_i32 : i32362 ! CHECK-NEXT: cf.cond_br363 if (i <= 6) goto 9364 ! CHECK-DAG: arith.muli {{.*}}, %c10000_i32 : i32365 n = i * 10000366 case default367 ! CHECK-DAG: arith.muli {{.*}}, %c100_i32 : i32368 n = i * 100369 9 end select370 print*, n371 enddo372 ! CHECK: return373 end374 375 ! CHECK-LABEL: func @_QPswhere376 subroutine swhere(num)377 implicit none378 379 integer, intent(in) :: num380 real, dimension(1) :: array381 382 array = 0.0383 384 ! CHECK: fir.select_case {{.*}} : i32 [#fir.point, %c1_i32, ^bb1, unit, ^bb2]385 select case (num)386 case (1)387 ! CHECK: fir.do_loop388 where (array >= 0.0)389 array = 42390 end where391 case default392 array = -1393 end select394 ! CHECK: cf.br ^bb3395 print*, array(1)396 end subroutine swhere397 398 ! CHECK-LABEL: func @_QPsforall399 subroutine sforall(num)400 implicit none401 402 integer, intent(in) :: num403 real, dimension(1) :: array404 integer :: i405 406 array = 0.0407 408 ! CHECK: fir.select_case {{.*}} : i32 [#fir.point, %c1_i32, ^bb1, unit, ^bb2]409 select case (num)410 case (1)411 ! CHECK: fir.do_loop412 forall (i = 1:size(array)) array(i) = 42413 case default414 array = -1415 end select416 ! CHECK: cf.br ^bb3417 print*, array(1)418 end subroutine sforall419 420 ! CHECK-LABEL: func @_QPsnested421 subroutine snested(str)422 character(*), optional :: str423 integer :: num424 425 ! CHECK: fir.is_present426 if (present(str)) then427 ! CHECK: fir.call @_FortranATrim428 select case (trim(str))429 ! == 'a'430 ! CHECK-O0: fir.call @_FortranACharacterCompareScalar1431 ! CHECK-O0-NEXT: arith.cmpi eq, {{.*}}, %c0_i32 : i32432 ! CHECK-O1: fir.do_loop {{.*}} -> (i8) {433 ! CHECK-O1: arith.cmpi eq, %{{[0-9]+}}, %c{{[0-9]+}}_i8 : i8434 case ('a')435 ! CHECK-DAG: fir.store %c10_i32 to {{.*}} : !fir.ref<i32>436 num = 10437 case default438 ! CHECK-DAG: fir.store %c20_i32 to {{.*}} : !fir.ref<i32>439 num = 20440 end select441 else442 ! CHECK-DAG: fir.store %c30_i32 to {{.*}} : !fir.ref<i32>443 num = 30444 end if445 end subroutine snested446 447 ! CHECK-LABEL: main448 program p449 integer sinteger, v(10)450 451 n = -10452 do j = 1, 4453 do k = 1, 10454 n = n + 1455 v(k) = sinteger(n)456 enddo457 ! expected output: 1 1 1 1 1 1 1 1 1 1458 ! 1 2 3 4 4 6 7 7 7 7459 ! 7 7 7 7 7 0 0 0 0 0460 ! 7 7 7 7 7 7 7 7 7 7461 print*, v462 enddo463 464 print*465 call slogical(.false.) ! expected output: 0 1 0 3 1 1 3 1466 call slogical(.true.) ! expected output: 0 0 2 3 2 3 2 2467 468 print*469 call scharacter('aa') ! expected output: 10470 call scharacter('d') ! expected output: 10471 call scharacter('f') ! expected output: -1472 call scharacter('ff') ! expected output: 20473 call scharacter('fff') ! expected output: 20474 call scharacter('ffff') ! expected output: 20475 call scharacter('fffff') ! expected output: -1476 call scharacter('jj') ! expected output: -1477 call scharacter('m') ! expected output: 30478 call scharacter('q') ! expected output: -1479 call scharacter('qq') ! expected output: 40480 call scharacter('qqq') ! expected output: -1481 call scharacter('vv') ! expected output: -1482 call scharacter('xx') ! expected output: 50483 call scharacter('zz') ! expected output: 50484 485 print*486 call scharacter1('99 ') ! expected output: 4487 call scharacter1('88 ') ! expected output: 4488 call scharacter1('77 ') ! expected output: 4489 call scharacter1('66 ') ! expected output: 4490 call scharacter1('55 ') ! expected output: 4491 call scharacter1('44 ') ! expected output: 4492 call scharacter1('33 ') ! expected output: 3493 call scharacter1('22 ') ! expected output: 2494 call scharacter1('11 ') ! expected output: 1495 call scharacter1('00 ') ! expected output: 0496 call scharacter1('. ') ! expected output: 0497 call scharacter1(' ') ! expected output: 0498 499 print*500 call scharacter2('99 ') ! expected output: 9 -2501 call scharacter2('22 ') ! expected output: 9 -2502 call scharacter2('. ') ! expected output: 9 -2503 call scharacter2(' ') ! expected output: 9 -2504 505 print*506 call sempty(0) ! expected output: 0 i:case default 0; c:case default507 call sempty(1) ! expected output: 1 i:case 1; 1 c:case 1508 call sempty(2) ! no output509 call sempty(3) ! expected output: 3 i:case default; 3 c:case default510 511 print*512 call sgoto ! expected output: 10 20 300 400 5000 6000 70000 80000513 514 print*515 call swhere(1) ! expected output: 42.516 call sforall(1) ! expected output: 42.517 end518