реклама на сайте
подробности

 
 
> Кривой оптимизатор IAR? (IAR V6.21.1.52794/W32 for ARM)
jcxz
сообщение Aug 20 2012, 06:47
Сообщение #1


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Имеем (Cortex-M3):
Код
s32 c;  //signed int
if ((u32)c < 100000) {   //проверка как unsigned int
  ...
} else {
  if (c >= 0) i += 1;      //проверка как signed int
  i += 1;
}

После компиляции с полной оптимизацией получаем бред:
Код
;if ((u32)c < 100000) {
              LDR.W    R0,??DataTable21_14;; 0x186a0
              CMP      R5,R0
              BCS.N    ??isrTIMER1_13
              ...
              B.N      ??isrTIMER1_14
;} else {
;  if (c >= 0) i += 1;
  ??isrTIMER1_13:
              ADDS     R0,R4,#+1;почему безусловно??? Где IT???
              ...
;  i += 1;
              ADDS     R4,R0,#+1
;}
  ??isrTIMER1_14:
              ...

Куда делось условное исполнение: if (c >= 0) i += 1; ????

Если поставить оптимизацию "Low", то всё нормально - эта строка выполняется по условию (с помощью команд перехода).
При компиляции V5.50.0.51878/W32 for ARM тоже всё ок - строка выполняется условно (с помощью команды IT).
IAR-цы добавили новый баг в оптимизатор?
У кого есть IAR более новый - можете проверить - исправлено это или ещё нет?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
scifi
сообщение Aug 20 2012, 07:11
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Попробовал такой код:
Код
int
test(int c, int i)
{
  if ((unsigned)c < 100000) {   //проверка как unsigned int
  } else {
    if (c >= 0) i += 1;      //проверка как signed int
    i += 1;
  }
  return i;
}

Вроде бы всё правильно скомпилировалось:
CODE
if ((unsigned)c < 100000) { //i?iaa?ea eae unsigned int
test:
0x8000040: 0x4a04 LDR.N R2, ??test_0 ; 0x186a0 (100000)
0x8000042: 0x4290 CMP R0, R2
0x8000044: 0xd303 BCC.N ??test_1 ; 0x800004e
if (c >= 0) i += 1; //i?iaa?ea eae signed int
0x8000046: 0x2800 CMP R0, #0
0x8000048: 0xbf58 IT PL
0x800004a: 0x1c49 ADDPL R1, R1, #1
i += 1;
0x800004c: 0x1c49 ADDS R1, R1, #1
return i;
??test_1:
0x800004e: 0x4608 MOV R0, R1
0x8000050: 0x4770 BX LR
0x8000052: 0xbf00 NOP
??test_0:
0x8000054: 0x000186a0 DC32 100000 ; ' †..'

Яр 6.40.1.3832.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Aug 20 2012, 08:10
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Да, Ваш и у меня правильно компилится. И если мою функцию урезать - тоже начинает правильно. Но в изначальном виде - баг!
Приведу функцию в исходном виде (почти как у меня в рабочем варианте). Извините что так много, но при урезании функции начинает нормально компилить. %-\

CODE
#define WATCH_BASE_CLK 1000000 //[Hz] дискретность nTIM_watch
#define T_ADJ 16 //разрядность фильтра джиттера ISR RTC
typedef signed char s8;
typedef signed short s16;
typedef signed int s32;
typedef signed long long s64;
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned long long u64;
enum {
SHIFT_STATE_INIT, SHIFT_STATE_IDLE, SHIFT_STATE_REQ, SHIFT_STATE_ACT,
SHIFT_STATE_REPORT, SHIFT_STATE_SYNC};
u32 volatile shadowRTC;
u32 shiftPoint, pointTIM;
u16 adjTim;
u8 stateTIM = 0;
u8 shiftState;
s8 shiftSec;
s32 shiftMs;
typedef struct {
u32 IR;
u32 TCR;
u32 TC;
u32 PR;
u32 PC;
u32 MCR;
u32 MR[4];
u32 CCR;
u32 CR[2];
u32 unuse0[2];
u32 EMR;
u32 unuse1[12];
u32 CTCR;
} HwRegsTIMER;
__no_init extern volatile HwRegsTIMER TIMER_0 @ ".HwRegsTIMER0";

u32 GetMcsTimer() { return TIMER_0.TC; }

extern "C" void TBug()
{
static s8 secAdd;
u32 i, j = GetMcsTimer();
s32 c, cc;
volatile HwRegsTIMER *p = &TIMER_0;
p->IR = 2;
switch (i = stateTIM) {
case 12: stateTIM = 11; return;
case 10:
case 2:
if ((c = p->MR[1] - WATCH_BASE_CLK / 2) < 0) c += WATCH_BASE_CLK;
p->MR[1] = c;
stateTIM = i + 1;
return;
case 11:
shiftState = SHIFT_STATE_REPORT;
// PingWatch();
case 3:
shadowRTC += secAdd;
if (stateTIM = i >>= 3) break;
case 0:
if (shiftPoint == shadowRTC + 1 && shiftState == SHIFT_STATE_REQ) {
shiftState = SHIFT_STATE_ACT;
c = shiftMs;
cc = shiftSec;
i = 10;
}
case 1:
if (i < 2) {
stateTIM = 0;
if (adjTim & (1 << T_ADJ - 1) - 1) {
c = adjTim;
adjTim = cc = 0;
i = 2;
} else break;
}
secAdd = cc;
if ((u32)c < WATCH_BASE_CLK / 10) {
if ((c += p->MR[1] - WATCH_BASE_CLK / 2) < 0) c += WATCH_BASE_CLK;
p->MR[1] = c;
} else {
if (c >= 0) i += 1;
if ((c += p->MR[1]) < 0) c += WATCH_BASE_CLK;
if (c >= WATCH_BASE_CLK) c -= WATCH_BASE_CLK;
p->MR[1] = c;
i += 1;
}
stateTIM = i;
}
pointTIM = j;
shadowRTC++;
/// PostEventRTC();
}

Вот что получается (см. метки ??TBug_9 и ??TBug_10):
CODE
513 extern "C" void TBug()
514 {
\ TBug:
\ 00000000 F8B5 PUSH {R3-R7,LR}
515 static s8 secAdd;
516 u32 i, j = GetMcsTimer();
\ 00000002 ........ BL _Z11GetMcsTimerv
517 s32 c, cc;
518 volatile HwRegsTIMER *p = &TIMER_0;
519 p->IR = B1;
\ 00000006 .... LDR.N R2,??DataTable67_11
\ 00000008 0221 MOVS R1,#+2
\ 0000000A 1160 STR R1,[R2, #+0]
520 switch (i = stateTIM) {
\ 0000000C .... LDR.N R1,??DataTable67_12
\ 0000000E 0C78 LDRB R4,[R1, #+0]
\ 00000010 0C2C CMP R4,#+12
\ 00000012 52D8 BHI.N ??TBug_1
\ 00000014 DFE804F0 TBB [PC, R4]
\ ??TBug_0:
\ 00000018 1E2D0A15 DC8 0x1E,0x2D,0xA,0x15
\ 0000001C 51515151 DC8 0x51,0x51,0x51,0x51
\ 00000020 51510A13 DC8 0x51,0x51,0xA,0x13
\ 00000024 0700 DC8 0x7,0x0
521 case 12: stateTIM = 11; return;
\ ??TBug_2:
\ 00000026 0B20 MOVS R0,#+11
\ ??TBug_3:
\ 00000028 0870 STRB R0,[R1, #+0]
\ 0000002A F1BD POP {R0,R4-R7,PC}
522 case 10:
523 case 2:
524 if ((c = p->MR[1] - WATCH_BASE_CLK / 2) < 0) c += WATCH_BASE_CLK;
\ ??TBug_4:
\ 0000002C D069 LDR R0,[R2, #+28]
\ 0000002E .... LDR.N R3,??DataTable67_13;; 0xfff85ee0
\ 00000030 1B18 ADDS R3,R3,R0
\ 00000032 44BF ITT MI
\ 00000034 .... LDRMI.N R0,??DataTable67_2;; 0xf4240
\ 00000036 C318 ADDMI R3,R0,R3
525 p->MR[1] = c;
\ 00000038 D361 STR R3,[R2, #+28]
526 stateTIM = i + 1;
\ 0000003A 601C ADDS R0,R4,#+1
\ 0000003C F4E7 B.N ??TBug_3
527 return;
528 case 11:
529 shiftState = SHIFT_STATE_REPORT;
\ ??TBug_5:
\ 0000003E 0426 MOVS R6,#+4
\ 00000040 4E70 STRB R6,[R1, #+1]
530 // PingWatch();
531 case 3:
532 shadowRTC += secAdd;
\ ??TBug_6:
\ 00000042 8E68 LDR R6,[R1, #+8]
\ 00000044 91F90270 LDRSB R7,[R1, #+2]
\ 00000048 BE19 ADDS R6,R7,R6
\ 0000004A 8E60 STR R6,[R1, #+8]
533 if (stateTIM = i >>= 3) break;
\ 0000004C E408 LSRS R4,R4,#+3
\ 0000004E 0C70 STRB R4,[R1, #+0]
\ 00000050 0E78 LDRB R6,[R1, #+0]
\ 00000052 96BB CBNZ.N R6,??TBug_1
534 case 0:
535 if (shiftPoint == shadowRTC + 1 && shiftState == SHIFT_STATE_REQ) {
\ ??TBug_7:
\ 00000054 CE68 LDR R6,[R1, #+12]
\ 00000056 8F68 LDR R7,[R1, #+8]
\ 00000058 7F1C ADDS R7,R7,#+1
\ 0000005A BE42 CMP R6,R7
\ 0000005C 09D1 BNE.N ??TBug_8
\ 0000005E 4E78 LDRB R6,[R1, #+1]
\ 00000060 022E CMP R6,#+2
\ 00000062 06D1 BNE.N ??TBug_8
536 shiftState = SHIFT_STATE_ACT;
\ 00000064 0323 MOVS R3,#+3
\ 00000066 4B70 STRB R3,[R1, #+1]
537 c = shiftMs;
\ 00000068 4B69 LDR R3,[R1, #+20]
538 cc = shiftSec;
\ 0000006A 91F90650 LDRSB R5,[R1, #+6]
539 i = 10;
\ 0000006E 0A24 MOVS R4,#+10
\ 00000070 09E0 B.N ??TBug_9
540 }
541 case 1:
542 if (i < 2) {
\ ??TBug_8:
\ 00000072 022C CMP R4,#+2
\ 00000074 07D2 BCS.N ??TBug_9
543 stateTIM = 0;
\ 00000076 0023 MOVS R3,#+0
\ 00000078 0B70 STRB R3,[R1, #+0]
544 if (adjTim & (1 << T_ADJ - 1) - 1) {
\ 0000007A 8B88 LDRH R3,[R1, #+4]
\ 0000007C 5C04 LSLS R4,R3,#+17
\ 0000007E 1CD0 BEQ.N ??TBug_1
545 c = adjTim;
546 adjTim = cc = 0;
\ 00000080 0025 MOVS R5,#+0
\ 00000082 8D80 STRH R5,[R1, #+4]
547 i = 2;
\ 00000084 0224 MOVS R4,#+2
548 } else break;
549 }
550 secAdd = cc;
\ ??TBug_9:
\ 00000086 8D70 STRB R5,[R1, #+2]
551 if ((u32)c < WATCH_BASE_CLK / 10) {
\ 00000088 .... LDR.N R5,??DataTable67_14;; 0x186a0
\ 0000008A AB42 CMP R3,R5
\ 0000008C 08D2 BCS.N ??TBug_10
552 if ((c += p->MR[1] - WATCH_BASE_CLK / 2) < 0) c += WATCH_BASE_CLK;
\ 0000008E D569 LDR R5,[R2, #+28]
\ 00000090 EB18 ADDS R3,R5,R3
\ 00000092 .... LDR.N R5,??DataTable67_13;; 0xfff85ee0
\ 00000094 EB18 ADDS R3,R5,R3
\ 00000096 44BF ITT MI
\ 00000098 .... LDRMI.N R5,??DataTable67_2;; 0xf4240
\ 0000009A EB18 ADDMI R3,R5,R3
553 p->MR[1] = c;
\ 0000009C D361 STR R3,[R2, #+28]
\ 0000009E 0BE0 B.N ??TBug_11
554 } else {
555 if (c >= 0) i += 1;
\ ??TBug_10:
\ 000000A0 641C ADDS R4,R4,#+1
556 if ((c += p->MR[1]) < 0) c += WATCH_BASE_CLK;
\ 000000A2 D569 LDR R5,[R2, #+28]
\ 000000A4 EB18 ADDS R3,R5,R3
\ 000000A6 .... LDR.N R5,??DataTable67_2;; 0xf4240
\ 000000A8 48BF IT MI
\ 000000AA EB18 ADDMI R3,R5,R3
557 if (c >= WATCH_BASE_CLK) c -= WATCH_BASE_CLK;
\ 000000AC AB42 CMP R3,R5
\ 000000AE A4BF ITT GE
\ 000000B0 .... LDRGE.N R5,??DataTable67_5;; 0xfff0bdc0
\ 000000B2 EB18 ADDGE R3,R5,R3
558 p->MR[1] = c;
\ 000000B4 D361 STR R3,[R2, #+28]
559 i += 1;
\ 000000B6 641C ADDS R4,R4,#+1
560 }
561 stateTIM = i;
\ ??TBug_11:
\ 000000B8 0C70 STRB R4,[R1, #+0]
562 }
563 pointTIM = j;
\ ??TBug_1:
\ 000000BA 0861 STR R0,[R1, #+16]
564 shadowRTC++;
\ 000000BC 8868 LDR R0,[R1, #+8]
\ 000000BE 401C ADDS R0,R0,#+1
\ 000000C0 8860 STR R0,[R1, #+8]
565 /// PostEventRTC();
566 }
\ 000000C2 F1BD POP {R0,R4-R7,PC} ;; return


Можете это попробовать скомпилить? Скопировал сюда вроде все необходимые define и определения типов.

Сообщение отредактировал IgorKossak - Aug 20 2012, 14:11
Причина редактирования: концевые табы!!!
Go to the top of the page
 
+Quote Post
scifi
сообщение Aug 20 2012, 08:17
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(jcxz @ Aug 20 2012, 12:10) *
Можете это попробовать скомпилить? Скопировал сюда вроде все необходимые define и определения типов.

Попробовал - не компилится, причём по очевидным причинам. Если сделаете пример, который действительно можно вставить в пустой проект и скомпилировать, тогда попробую.

Update:
Да, и здесь принято длинные куски кода заворачивать в теги CODEBOX. Не напрягайте модераторов без необходимости - подкорректируйте сами.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Aug 20 2012, 08:56
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Создал пустой проект, скомпилил, цепляю сюда аттачем. Прикрепленный файл  SRC.2.ZIP ( 23.78 килобайт ) Кол-во скачиваний: 97


Цитата(ArtemKAD @ Aug 20 2012, 14:51) *
Компилятор посмотрел, что результат от этого кода нигде не используется и благополучно его выкинул.

Во-первых: используется, смотрите внимательнее.
Во-вторых: не выкинул, а сделал безусловным, смотрите внимательнее.
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- jcxz   Кривой оптимизатор IAR? (IAR V6.21.1.52794/W32 for ARM)   Aug 20 2012, 06:47
- - ArtemKAD   ЦитатаКуда делось условное исполнение: if (c >=...   Aug 20 2012, 08:51
- - ArtemKAD   ЦитатаВо-первых: используется, смотрите внимательн...   Aug 20 2012, 09:04
|- - jcxz   Видно: Код 561 stateTIM = i; ...   Aug 20 2012, 09:30
- - scifi   Семён Семёныч! У вас прямо перед сравнением пе...   Aug 20 2012, 12:36
|- - jcxz   Цитата(scifi @ Aug 20 2012, 18:36) Семён ...   Aug 20 2012, 14:39
|- - scifi   RE: Кривой оптимизатор IAR? (IAR V6.21.1.52794/W32 for ARM)   Aug 20 2012, 14:56
|- - jcxz   Цитата(scifi @ Aug 20 2012, 20:56) Нет си...   Aug 20 2012, 15:28
- - Андрей190   Кодs32 c; //signed int if ((u32)c ...   Aug 21 2012, 07:43
|- - jcxz   Как раз специально для Вас я написал комменты Обр...   Aug 21 2012, 07:52
- - scifi   Ну да, похоже на баг. Хорошо бы написать баг-репор...   Aug 21 2012, 07:59
- - jcxz   Чем дальше в лес, тем больше дров.... Ещё один баг...   Aug 23 2012, 08:46


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 6th August 2025 - 16:21
Рейтинг@Mail.ru


Страница сгенерированна за 0.01445 секунд с 7
ELECTRONIX ©2004-2016