const 1 24 августа Опубликовано 24 августа · Жалоба IAR ARM 6.50.3.4757 сам код, упрощен до максимума extern void foo(uint8_t b); uint8_t glb; void tst(void) { static uint8_t sv; uint8_t tmp; if (sv != (glb & (1 << 6))) { sv = (glb & (1 << 6)); tmp = (sv)? 0x00 : 0xFF; foo(tmp); } } int main() { while(1) { tst(); } } листинг для оптимизации High Balanced 27 void tst(void) 28 { 29 static uint8_t sv; 30 uint8_t tmp; 31 32 if (sv != (glb & (1 << 6))) { \ `tst`: \ 00000000 0x.... LDR.N R0,??DataTable3_1 \ 00000002 0x7801 LDRB R1,[R0, #+0] // glb \ 00000004 0x7842 LDRB R2,[R0, #+1] // sv \ 00000006 0xF001 0x0340 AND R3,R1,#0x40 // R3 = glb & (1 << 6) \ 0000000A 0x429A CMP R2,R3 \ 0000000C 0xD006 BEQ.N ??tst_0 33 sv = (glb & (1 << 6)); \ 0000000E 0x7041 STRB R1,[R0, #+1] // sv = glb а не sv = glb & (1 << 6) 34 tmp = (sv)? 0x00 : 0xFF; \ 00000010 0x0648 LSLS R0,R1,#+25 \ 00000012 0xBF4C ITE MI \ 00000014 0x2000 MOVMI R0,#+0 \ 00000016 0x20FF MOVPL R0,#+255 35 foo(tmp); \ 00000018 0x.... 0x.... B.W foo 36 } 37 38 } \ ??tst_0: \ 0000001C 0x4770 BX LR ;; return листинг для оптимизации Medium 27 void tst(void) 28 { 29 static uint8_t sv; 30 uint8_t tmp; 31 32 if (sv != (glb & (1 << 6))) { \ `tst`: \ 00000000 0x.... LDR.N R0,??DataTable2_1 \ 00000002 0x7801 LDRB R1,[R0, #+0] // glb \ 00000004 0x7842 LDRB R2,[R0, #+1] // sv \ 00000006 0xF001 0x0340 AND R3,R1,#0x40 // R3 = glb & (1 << 6) \ 0000000A 0x429A CMP R2,R3 \ 0000000C 0xD008 BEQ.N ??tst_0 33 sv = (glb & (1 << 6)); \ 0000000E 0xF011 0x0140 ANDS R1,R1,#0x40 // R1 = glb & (1 << 6) \ 00000012 0x7041 STRB R1,[R0, #+1] // sv = glb & (1 << 6) как надо 34 tmp = (sv)? 0x00 : 0xFF; \ 00000014 0xD001 BEQ.N ??tst_1 \ 00000016 0x2000 MOVS R0,#+0 \ 00000018 0xE000 B.N ??tst_2 \ ??tst_1: \ 0000001A 0x20FF MOVS R0,#+255 35 foo(tmp); \ ??tst_2: \ 0000001C 0x.... 0x.... B.W foo 36 } 37 38 } \ ??tst_0: \ 00000020 0x4770 BX LR ;; return листинг для оптимизации High Balanced и дополнительной переменной extern void foo(uint8_t b); uint8_t glb; void tst(void) { static uint8_t sv; uint8_t tmp, tmp2; tmp2 = glb & (1 << 6); if (sv != tmp2) { sv = tmp2; tmp = (sv)? 0x00 : 0xFF; foo(tmp); } } int main() { while(1) { tst(); } } 27 void tst(void) 28 { 29 static uint8_t sv; 30 uint8_t tmp, tmp2; 31 32 tmp2 = glb & (1 << 6); \ `tst`: \ 00000000 0x.... LDR.N R0,??DataTable3_1 \ 00000002 0x7801 LDRB R1,[R0, #+0] // glb 33 if (sv != tmp2) { \ 00000004 0x7843 LDRB R3,[R0, #+1] // sv \ 00000006 0xF001 0x0140 AND R1,R1,#0x40 // R1 = glb & (1 << 6) \ 0000000A 0x428B CMP R3,R1 \ 0000000C 0xD006 BEQ.N ??tst_0 34 sv = tmp2; \ 0000000E 0x7041 STRB R1,[R0, #+1] // sv = glb & (1 << 6) как надо 35 tmp = (sv)? 0x00 : 0xFF; \ 00000010 0x2900 CMP R1,#+0 \ 00000012 0xBF14 ITE NE \ 00000014 0x2000 MOVNE R0,#+0 \ 00000016 0x20FF MOVEQ R0,#+255 36 foo(tmp); \ 00000018 0x.... 0x.... B.W foo 37 } 38 39 } \ ??tst_0: \ 0000001C 0x4770 BX LR ;; return Почему так, где ошибка? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 187 24 августа Опубликовано 24 августа · Жалоба Вы уточните, где вы видите ошибку, просто так просматривать сотню строк листинга вряд ли кому-то интересно. А, вижу комментарии. Ничего криминального компилятор не вычудил, ошибок нет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
const 1 24 августа Опубликовано 24 августа · Жалоба 4 minutes ago, Arlleex said: Вы уточните, где вы видите ошибку, просто так просматривать сотню строк листинга вряд ли кому-то интересно. отмечено коментариями в листингах. В одном случае в переменную sv записывается (glb & (1 << 6)) (как надо), в другом glb (не правильно). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 187 24 августа Опубликовано 24 августа · Жалоба 1 минуту назад, const сказал: отмечено коментариями в листингах. В одном случае в переменную sv записывается (glb & (1 << 6)) (как надо), в другом glb (не правильно). С токи зрения наблюдаемого поведения Си-программы она полностью корректна. По сути будете получать один и тот же результат. Подумайте: если бы при оптимизации компилятор все равно транслировал "в лоб" все написанное, на кой были бы нужны все эти хитрые уровни оптимизаций? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
const 1 24 августа Опубликовано 24 августа (изменено) · Жалоба @Arlleex Программа корректна, а результат компиляции нет. Не изменяя программу, а только уровень оптимизации, получаем разный результат (алгоритм). А добавляя промежуточную переменную в "нерабочую" оптимизацию, получаем корректный результат. И еще. IAR ARM 8.30.1.17148 - компилирует правильно Изменено 24 августа пользователем const Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_pv 79 24 августа Опубликовано 24 августа · Жалоба 24 minutes ago, const said: Программа корректна, а результат компиляции нет. в "упрощённой" версии и glb и sv всегда равны 0, не понятно почему целиком всё не выкинул, а только присвоение "соптимизировал". 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
const 1 24 августа Опубликовано 24 августа (изменено) · Жалоба 13 minutes ago, _pv said: в "упрощённой" версии и glb и sv всегда равны 0, не понятно почему целиком всё не выкинул, а только присвоение "соптимизировал". почему же компиляция при разных уровнях оптимизации разнится, как и при добавлении дополнительной переменной. Да и более свежий компилятор дает правильный код. Что по вашему надо добавить, что бы код для компилятора был "правильный"? Проект на 1000+ строк не вижу надобности выкладывать. Проблему изолировал. вот что получается когда делаю переменную glb volatile (оптимизация High Balanced) 27 void tst(void) 28 { 29 static uint8_t sv; 30 uint8_t tmp; 31 32 if (sv != (glb & (1 << 6))) { \ `tst`: \ 00000000 0x.... LDR.N R0,??DataTable3_1 \ 00000002 0x7841 LDRB R1,[R0, #+1] \ 00000004 0x7802 LDRB R2,[R0, #+0] \ 00000006 0xF002 0x0240 AND R2,R2,#0x40 \ 0000000A 0x4291 CMP R1,R2 \ 0000000C 0xD007 BEQ.N ??tst_0 33 sv = (glb & (1 << 6)); \ 0000000E 0x7801 LDRB R1,[R0, #+0] // операция "& (1 << 6)" игнорируется \ 00000010 0x7041 STRB R1,[R0, #+1] 34 tmp = (sv)? 0x00 : 0xFF; \ 00000012 0x0648 LSLS R0,R1,#+25 \ 00000014 0xBF4C ITE MI \ 00000016 0x2000 MOVMI R0,#+0 \ 00000018 0x20FF MOVPL R0,#+255 35 foo(tmp); \ 0000001A 0x.... 0x.... B.W foo 36 } 37 38 } \ ??tst_0: \ 0000001E 0x4770 BX LR ;; return Изменено 24 августа пользователем const Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 242 24 августа Опубликовано 24 августа · Жалоба 1 час назад, const сказал: IAR ARM 6.50.3.4757 Я бы не стал пользоваться IAR-ами до 7.80.4. Зачем вам такое старьё??? (да и с более новыми в некоторых случаях нужно быть осторожным; но по-крайней мере если не используется FPU и некоторые intrinsinc-и, то в 7.80.4 багов не замечал) 21 минуту назад, const сказал: Проект на 1000+ строк не вижу надобности выкладывать. Проблему изолировал. 1 час назад, const сказал: Почему так, где ошибка? Как версия (что может быть): где-то в этих 1000+ строках у вас объявлена или определена другая переменная с таким же именем (glb), но другого типа. Возможно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
const 1 24 августа Опубликовано 24 августа (изменено) · Жалоба @jcxz нет, переменная с таким именем одна. Ну а как же мой "изолированный" пример, разве такое поведение компилятора корректно? З.Ы. Оно соответствует поведению в моем проекте. Изменено 24 августа пользователем const Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 242 24 августа Опубликовано 24 августа · Жалоба 3 минуты назад, const сказал: @jcxz нет, переменная с таким иминем одна. Ну а как же мой "изолированный" пример, разве такое поведение компилятора корректно? А кто вас заставляет пользоваться неисправным инструментом, вместо того, чтобы взять исправный? 6 минут назад, const сказал: нет, переменная с таким именем одна. Может быть и не переменная, а например - макрос. Ну или любой объект с таким именем. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 24 августа Опубликовано 24 августа · Жалоба 42 минуты назад, const сказал: почему же компиляция при разных уровнях оптимизации разнится, как и при добавлении дополнительной переменной. Разнятся исходные условия, разнится и результат компиляции. При этом наблюдаемое поведение программы не меняется, результат компиляции корректный во всех случаях. 42 минуты назад, const сказал: Да и более свежий компилятор дает правильный код. Этот компилятор тоже дает правильный код. Результатом работы (наблюдаемым поведением) является значения аргумента вызова функции foo(). Значения переменных sv, tmp не являются наблюдаемым поведением, поэтому их значение может быть любым (их может вообще не быть в исполняемом коде), пока в foo() передается правильное значение. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
const 1 24 августа Опубликовано 24 августа · Жалоба @jcxz не заставляют. После найденой ошибки буду переходить на более свежий IAR. Имя неповторимое (оно не glb). Проблема же в неправильном присвоении значения переменной sv. Вопрос задал так как решил, что что-то упускаю. Видемо и в самом деле компилятор глючит. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 24 августа Опубликовано 24 августа · Жалоба 43 минуты назад, const сказал: вот что получается когда делаю переменную glb volatile Что просите, то и получаете. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
const 1 24 августа Опубликовано 24 августа (изменено) · Жалоба @Сергей Борщ При повторном вызове ф-ции tst при неизменной переменной glb, ф-ция foo вызываться не должна 2 minutes ago, Сергей Борщ said: Что просите, то и получаете. я прошу sv = glb & (1 << 6) а получаю sv = glb Изменено 24 августа пользователем const Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 242 24 августа Опубликовано 24 августа · Жалоба 19 минут назад, Сергей Борщ сказал: Разнятся исходные условия, разнится и результат компиляции. При этом наблюдаемое поведение программы не меняется, результат компиляции корректный во всех случаях. Результат работы программы при "high balanced" оптимизации и при "medium" будет разный. А значит компилятор неправ. Как бы он ни оптимизировал код, результат выполнения меняться не должен. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться