{"action":"created","issue":{"url":"https://api.github.com/repos/riscv/riscv-gnu-toolchain/issues/89","labels_url":"https://api.github.com/repos/riscv/riscv-gnu-toolchain/issues/89/labels{/name}","comments_url":"https://api.github.com/repos/riscv/riscv-gnu-toolchain/issues/89/comments","events_url":"https://api.github.com/repos/riscv/riscv-gnu-toolchain/issues/89/events","html_url":"https://github.com/riscv/riscv-gnu-toolchain/issues/89","id":107941895,"number":89,"title":"signed char gcc bug","user":{"login":"jmcddn","id":1395215,"avatar_url":"https://avatars.githubusercontent.com/u/1395215?v=3","gravatar_id":"","url":"https://api.github.com/users/jmcddn","html_url":"https://github.com/jmcddn","followers_url":"https://api.github.com/users/jmcddn/followers","following_url":"https://api.github.com/users/jmcddn/following{/other_user}","gists_url":"https://api.github.com/users/jmcddn/gists{/gist_id}","starred_url":"https://api.github.com/users/jmcddn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jmcddn/subscriptions","organizations_url":"https://api.github.com/users/jmcddn/orgs","repos_url":"https://api.github.com/users/jmcddn/repos","events_url":"https://api.github.com/users/jmcddn/events{/privacy}","received_events_url":"https://api.github.com/users/jmcddn/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":2,"created_at":"2015-09-23T15:09:29Z","updated_at":"2015-09-28T21:12:30Z","closed_at":null,"body":"Hello, \r\nI've found what I believe to be a bug in the risc-v gcc. As shown in the code below, I define a singed char, however, it is interpreted as unsigned. \r\n\r\n```c\r\nvoid chartest(char *x, char *y) {\r\n  if (*x < *y)\r\n    printf(\"c: %hhd < %hhd\\n\", *x, *y);\r\n  else\r\n    printf(\"c: %hhd > %hhd\\n\", *x, *y);\r\n}\r\n\r\nvoid uchartest(unsigned char *x, unsigned char *y) {\r\n  if (*x < *y)\r\n    printf(\"uc: %hhu < %hhu\\n\", *x, *y);\r\n  else\r\n    printf(\"uc: %hhu > %hhu\\n\", *x, *y);\r\n}\r\n\r\nint main(int argc, char **argv) {\r\n  {\r\n    char a = -1;\r\n    char b = 1;\r\n    chartest(&a, &b);\r\n  }\r\n  {\r\n    unsigned char a = -1;\r\n    unsigned char b = 1;\r\n    uchartest(&a, &b);\r\n  }\r\n  return 0;\r\n}\r\n```\r\n\r\nThe output of the above code compiled on Ubuntu 14.4 w/ gcc 4.9.2 : \r\n```\r\n$ ./bugtest-native \r\nc: -1 < 1\r\nuc: 255 > 1\r\n```\r\nThe output when compiled on riscv-gcc and run on spike:\r\n```\r\n$ spike pk bugtest-spike\r\nc: 255 > 1\r\nuc: 255 > 1\r\n```\r\n\r\nI looked into the assembly produced by riscv-gcc and see that chartest() and uchartest() both treat the arguments as unsigned.\r\n\r\n```\r\n0000000000010140 <chartest>:\r\n   10140:       00054783                lbu     a5,0(a0)\r\n   10144:       0005c603                lbu     a2,0(a1)\r\n   10148:       00078593                mv      a1,a5\r\n   1014c:       00c7e863                bltu    a5,a2,1015c <chartest+0x1c>\r\n   10150:       0001b537                lui     a0,0x1b\r\n   10154:       ca050513                addi    a0,a0,-864 # 1aca0 <__clz_tab+0x110>\r\n   10158:       2ac0006f                j       10404 <printf>\r\n   1015c:       0001b537                lui     a0,0x1b\r\n   10160:       c9050513                addi    a0,a0,-880 # 1ac90 <__clz_tab+0x100>\r\n   10164:       2a00006f                j       10404 <printf>\r\n\r\n0000000000010168 <uchartest>:\r\n   10168:       00054783                lbu     a5,0(a0)\r\n   1016c:       0005c603                lbu     a2,0(a1)\r\n   10170:       00078593                mv      a1,a5\r\n   10174:       00c7e863                bltu    a5,a2,10184 <uchartest+0x1c>\r\n   10178:       0001b537                lui     a0,0x1b\r\n   1017c:       cc850513                addi    a0,a0,-824 # 1acc8 <__clz_tab+0x138>\r\n   10180:       2840006f                j       10404 <printf>\r\n   10184:       0001b537                lui     a0,0x1b\r\n   10188:       cb050513                addi    a0,a0,-848 # 1acb0 <__clz_tab+0x120>\r\n   1018c:       2780006f                j       10404 <printf>\r\n```\r\n\r\nIf the compiler had generated \"lb\" instructions on lines 10140 and 10144 instead of \"lbu\" I would expect the correct behavior. "},"comment":{"url":"https://api.github.com/repos/riscv/riscv-gnu-toolchain/issues/comments/143875689","html_url":"https://github.com/riscv/riscv-gnu-toolchain/issues/89#issuecomment-143875689","issue_url":"https://api.github.com/repos/riscv/riscv-gnu-toolchain/issues/89","id":143875689,"user":{"login":"palmer-dabbelt","id":1383006,"avatar_url":"https://avatars.githubusercontent.com/u/1383006?v=3","gravatar_id":"","url":"https://api.github.com/users/palmer-dabbelt","html_url":"https://github.com/palmer-dabbelt","followers_url":"https://api.github.com/users/palmer-dabbelt/followers","following_url":"https://api.github.com/users/palmer-dabbelt/following{/other_user}","gists_url":"https://api.github.com/users/palmer-dabbelt/gists{/gist_id}","starred_url":"https://api.github.com/users/palmer-dabbelt/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/palmer-dabbelt/subscriptions","organizations_url":"https://api.github.com/users/palmer-dabbelt/orgs","repos_url":"https://api.github.com/users/palmer-dabbelt/repos","events_url":"https://api.github.com/users/palmer-dabbelt/events{/privacy}","received_events_url":"https://api.github.com/users/palmer-dabbelt/received_events","type":"User","site_admin":false},"created_at":"2015-09-28T21:12:30Z","updated_at":"2015-09-28T21:12:30Z","body":"C does not define if \"char\" is signed or unsigned:\r\n\r\nhttp://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf\r\n\"\r\nThe three types char, signed char, and unsigned char are collectively called\r\nthe character types. The implementation shall define char to have the same range,\r\nrepresentation, and behavior as either signed char or unsigned char.\r\n\"\r\n\r\nOur GCC port looks internally consistent to me:\r\n\r\n````\r\n$ riscv64-unknown-linux-gnu-gcc -dM -E -c /usr/riscv64-unknown-linux-gnu/usr/include/limits.h | grep CHAR_MIN\r\n#define SCHAR_MIN (-SCHAR_MAX - 1)\r\n#define __WCHAR_MIN__ (-__WCHAR_MAX__ - 1)\r\n#define CHAR_MIN 0\r\n````\r\n\r\n````\r\n$ cat -n riscv-gnu-toolchain/gcc/gcc/config/riscv/riscv.h  | grep DEFAULT_SIGNED_CHAR\r\n   859\t#define DEFAULT_SIGNED_CHAR 0\r\n````\r\n\r\nUnless I've missed something and it's explicitly stated somewhere that \"char\" is signed on RISC-V, I think this isn't actually a bug."}}