Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28892 Discussions

ascii character constant used as a select-case-value

riad_h_1
Novice
1,119 Views

Hi,

for some characters (in fact, those with ascii codes greater than 127), I observe different results depending on whether an `if-else` or a `select case` is used. Here is a minimal example that reproduces the issue:

use iso_fortran_env
implicit none
integer,                     parameter :: ascii = selected_char_kind ("ascii")
character(kind=ascii,len=1), parameter :: C1 = achar(128)
character(kind=ascii,len=1)            :: myc = C1

print*,'1) With select case:'
select case ( myc )
case ( C1 )
   print*,'   myc = C1'
case default
   print*,'   myc /= C1 (problem!)'
end select

print*,'2) With if-else:'
if ( myc == C1 ) then
   print*,'   myc = C1'
else
   print*,'   myc /= C1 (problem!)'
end if

end

When compiled with ifx 2024.1.2 I get:

 1) With select case:
    myc /= C1 (problem!)
 2) With if-else:
    myc = C1

No problem observed:

- when C1 = achar(from 0 to127).

- with other compilers (ifort, gfortran, nagfor)

 

Thanks

5 Replies
Steve_Lionel
Honored Contributor III
996 Views

I can easily reproduce this. Looking at the run-time assembly code I see this:

Steve_Lionel_0-1724771240712.png

The movsx does a sign-extended move of myc into register rax. The code then subtracts 128 and does a branch-if-equal to the C1 case. The problem is the sign extension, which should not have been done for a character value, messing up the compare. Compiler bug.

What's REALLY strange to me, though, is that if I ask for an assembly listing, I see different instructions. movsbq would be correct here. I'm not sure why the sub is in the assembly listing as subq, as that does not seem to be a valid mnemonic.

 

 

	movsbq	_UNNAMED_MAIN$$$MYC(%rip), %rax
	subq	$128, %rax
	je	.LBB0_2
	jmp	.LBB0_1

 

 

 

 

 

0 Kudos
Xiaoping_D_Intel
Employee
831 Views

A bug report has been opened. We will fix it in the future product.


Regarding the different instructions showed in the VS debugging window and asm listing it is because by default ifx will generate the assembler output file in AT&T* syntax which is different from the Intel syntax in the debugging window. On Linux it can be changed with "-masm=intel" option.




Steve_Lionel
Honored Contributor III
799 Views

Thanks, but that should not change the movsx to a movsbq, an entirely different instruction. If it had actually generated movsbq, the bug would not be there.

0 Kudos
Xiaoping_D_Intel
Employee
726 Views

Hi Steve, in AT&T* syntax "movsbq" is the same instruction as "movsx" in Intel syntax. I found a online doc https://docs.oracle.com/cd/E53394_01/pdf/E54851.pdf which provides the mapping between these two sets of mnemonics. (movsbq is at page 38).




Steve_Lionel
Honored Contributor III
671 Views

Ah, ok. I was looking at a different reference. In that case, both movsx and movsbq are wrong in the generated code.

0 Kudos
Reply