tb0627b.pp 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. { %OPT=-O4 }
  2. program tb0627b;
  3. { tests for correctness various simplifications, done by the compiler }
  4. { we allow some expressions with side effects to be removed at the -O4
  5. optimization level, but we still disallow removing them for some of
  6. the simplificationss. This test checks that behaviour. }
  7. {$mode objfpc}
  8. { unfortunately, for this test, we need to mirror some defines from systemh.inc :( }
  9. { if the test fails on some platform, please first check whether these defines
  10. are up to date with the ones in the rtl }
  11. {------------------------------------------------------------------------------}
  12. {$ifdef FPC_HAS_INTERNAL_ROX}
  13. {$if defined(cpux86_64) or defined(cpui386) or defined(cpui8086)}
  14. {$define FPC_HAS_INTERNAL_ROX_BYTE}
  15. {$define FPC_HAS_INTERNAL_ROX_WORD}
  16. {$endif defined(cpux86_64) or defined(cpui386) or defined(cpui8086)}
  17. {$if defined(cpux86_64) or defined(cpui386) or defined(arm) or defined(powerpc) or defined(powerpc64) or defined(cpuaarch64)}
  18. {$define FPC_HAS_INTERNAL_ROX_DWORD}
  19. {$endif defined(cpux86_64) or defined(cpui386) or defined(arm) or defined(powerpc) or defined(powerpc64) or defined(cpuaarch64)}
  20. {$if defined(cpux86_64) or defined(powerpc64) or defined(cpuaarch64)}
  21. {$define FPC_HAS_INTERNAL_ROX_QWORD}
  22. {$define FPC_HAS_INTERNAL_ROX_ASSIGN_QWORD}
  23. {$endif defined(cpux86_64) or defined(powerpc64) or defined(cpuaarch64)}
  24. {$endif FPC_HAS_INTERNAL_ROX}
  25. {$ifdef FPC_HAS_INTERNAL_SAR}
  26. {$if defined(cpux86_64) or defined(cpui386) or defined(cpui8086) or defined(mips) or defined(mipsel) or defined(sparc)}
  27. {$define FPC_HAS_INTERNAL_SAR_BYTE}
  28. {$define FPC_HAS_INTERNAL_SAR_WORD}
  29. {$endif defined(cpux86_64) or defined(cpui386) or defined(cpui8086) or defined(mips) or defined(mipsel) or defined(sparc)}
  30. { currently, all supported CPUs have an internal 32 bit sar implementation }
  31. { $if defined(cpux86_64) or defined(cpui386) or defined(arm) or defined(powerpc) or defined(powerpc64) or defined(mips) or defined(mipsel)}
  32. {$define FPC_HAS_INTERNAL_SAR_DWORD}
  33. { $endif defined(cpux86_64) or defined(cpui386) or defined(arm) or defined(powerpc) or defined(powerpc64) or defined(mips) or defined(mipsel)}
  34. {$if defined(cpux86_64) or defined(powerpc64) or defined(cpuaarch64)}
  35. {$define FPC_HAS_INTERNAL_SAR_QWORD}
  36. {$define FPC_HAS_INTERNAL_SAR_ASSIGN_QWORD}
  37. {$endif defined(cpux86_64) or defined(powerpc64) or defined(cpuaarch64)}
  38. {$endif FPC_HAS_INTERNAL_SAR}
  39. {------------------------------------------------------------------------------}
  40. var
  41. SideEffectsHappened: Boolean = False;
  42. function s32_SideEffects: LongInt;
  43. begin
  44. SideEffectsHappened := True;
  45. Result := LongInt(Random($ffffffff));
  46. end;
  47. function u8_SideEffects: Byte;
  48. begin
  49. SideEffectsHappened := True;
  50. Result := Random(256);
  51. end;
  52. procedure CheckSideEffectsHappened;
  53. begin
  54. if not SideEffectsHappened then
  55. begin
  56. Writeln('Error! Side effects were removed!');
  57. Halt(1);
  58. end;
  59. SideEffectsHappened := False;
  60. end;
  61. procedure CheckNoSideEffectsHappened;
  62. begin
  63. if SideEffectsHappened then
  64. begin
  65. Writeln('Error! Side effects were expected to be removed, by they were not!');
  66. Halt(1);
  67. end;
  68. SideEffectsHappened := False;
  69. end;
  70. procedure Check(i64, expected_value: Int64);
  71. begin
  72. Write('+');
  73. if i64<>expected_value then
  74. begin
  75. Writeln('Error!');
  76. Halt(1);
  77. end;
  78. end;
  79. procedure Check(qw, expected_value: QWord);
  80. begin
  81. Write('+');
  82. if qw<>expected_value then
  83. begin
  84. Writeln('Error!');
  85. Halt(1);
  86. end;
  87. end;
  88. procedure Check(b, expected_value: Boolean);
  89. begin
  90. Write('+');
  91. if b<>expected_value then
  92. begin
  93. Writeln('Error!');
  94. Halt(1);
  95. end;
  96. end;
  97. procedure NoCheck(i64, expected_value: Int64);
  98. begin
  99. if i64<>expected_value then
  100. Write('.')
  101. else
  102. Write(',');
  103. end;
  104. procedure NoCheck(qw, expected_value: QWord);
  105. begin
  106. if qw<>expected_value then
  107. Write('.')
  108. else
  109. Write(',');
  110. end;
  111. procedure NoCheck(b, expected_value: Boolean);
  112. begin
  113. if b<>expected_value then
  114. Write('.')
  115. else
  116. Write(',');
  117. end;
  118. var
  119. I: Integer;
  120. begin
  121. for I := 1 to 100 do
  122. begin
  123. { many of these are now optimized at various -O settings }
  124. { we don't remove side effects for these: }
  125. NoCheck(s32_SideEffects-s32_SideEffects,0); CheckSideEffectsHappened;
  126. NoCheck(s32_SideEffects xor s32_SideEffects,0); CheckSideEffectsHappened;
  127. NoCheck(s32_SideEffects=s32_SideEffects, True); CheckSideEffectsHappened;
  128. NoCheck(s32_SideEffects<=s32_SideEffects, True); CheckSideEffectsHappened;
  129. NoCheck(s32_SideEffects>=s32_SideEffects, True); CheckSideEffectsHappened;
  130. NoCheck(s32_SideEffects<>s32_SideEffects, False); CheckSideEffectsHappened;
  131. NoCheck(s32_SideEffects<s32_SideEffects, False); CheckSideEffectsHappened;
  132. NoCheck(s32_SideEffects>s32_SideEffects, False); CheckSideEffectsHappened;
  133. { we remove side effects for these: }
  134. Check(0*s32_SideEffects, 0); CheckNoSideEffectsHappened;
  135. Check(s32_SideEffects*0, 0); CheckNoSideEffectsHappened;
  136. Check(0 and s32_SideEffects, 0); CheckNoSideEffectsHappened;
  137. Check(s32_SideEffects and 0, 0); CheckNoSideEffectsHappened;
  138. Check(0 shr s32_SideEffects, 0); CheckNoSideEffectsHappened;
  139. Check(0 shl s32_SideEffects, 0); CheckNoSideEffectsHappened;
  140. {$ifdef FPC_HAS_INTERNAL_SAR_BYTE}
  141. Check(SarShortInt(0, u8_SideEffects), 0); CheckNoSideEffectsHappened;
  142. Check(SarShortInt(ShortInt($ff), u8_SideEffects), -1); CheckNoSideEffectsHappened;
  143. {$else FPC_HAS_INTERNAL_SAR_BYTE}
  144. Check(SarShortInt(0, u8_SideEffects), 0); CheckSideEffectsHappened;
  145. Check(SarShortInt(ShortInt($ff), u8_SideEffects), -1); CheckSideEffectsHappened;
  146. {$endif FPC_HAS_INTERNAL_SAR_BYTE}
  147. {$ifdef FPC_HAS_INTERNAL_SAR_WORD}
  148. Check(SarSmallInt(0, u8_SideEffects), 0); CheckNoSideEffectsHappened;
  149. Check(SarSmallInt(SmallInt($ffff), u8_SideEffects), -1); CheckNoSideEffectsHappened;
  150. {$else FPC_HAS_INTERNAL_SAR_WORD}
  151. Check(SarSmallInt(0, u8_SideEffects), 0); CheckSideEffectsHappened;
  152. Check(SarSmallInt(SmallInt($ffff), u8_SideEffects), -1); CheckSideEffectsHappened;
  153. {$endif FPC_HAS_INTERNAL_SAR_WORD}
  154. {$ifdef FPC_HAS_INTERNAL_SAR_DWORD}
  155. Check(SarLongInt(0, u8_SideEffects), 0); CheckNoSideEffectsHappened;
  156. Check(SarLongInt(LongInt($ffffffff), u8_SideEffects), -1); CheckNoSideEffectsHappened;
  157. {$else FPC_HAS_INTERNAL_SAR_DWORD}
  158. Check(SarLongInt(0, u8_SideEffects), 0); CheckSideEffectsHappened;
  159. Check(SarLongInt(LongInt($ffffffff), u8_SideEffects), -1); CheckSideEffectsHappened;
  160. {$endif FPC_HAS_INTERNAL_SAR_DWORD}
  161. { SAR_QWORD is always handled inline in the compiler, regardless of
  162. the FPC_HAS_INTERNAL_SAR_QWORD define }
  163. //{$ifdef FPC_HAS_INTERNAL_SAR_QWORD}
  164. Check(SarInt64(0, u8_SideEffects), 0); CheckNoSideEffectsHappened;
  165. Check(SarInt64(Int64($ffffffffffffffff), u8_SideEffects), -1); CheckNoSideEffectsHappened;
  166. //{$else FPC_HAS_INTERNAL_SAR_QWORD}
  167. // Check(SarInt64(0, u8_SideEffects), 0); CheckSideEffectsHappened;
  168. // Check(SarInt64(Int64($ffffffffffffffff), u8_SideEffects), -1); CheckSideEffectsHappened;
  169. //{$endif FPC_HAS_INTERNAL_SAR_QWORD}
  170. {$ifdef FPC_HAS_INTERNAL_ROX_BYTE}
  171. Check(RorByte(0, u8_SideEffects), 0); CheckNoSideEffectsHappened;
  172. Check(RolByte(0, u8_SideEffects), 0); CheckNoSideEffectsHappened;
  173. Check(RorByte($ff, u8_SideEffects), $ff); CheckNoSideEffectsHappened;
  174. Check(RolByte($ff, u8_SideEffects), $ff); CheckNoSideEffectsHappened;
  175. {$else FPC_HAS_INTERNAL_ROX_BYTE}
  176. Check(RorByte(0, u8_SideEffects), 0); CheckSideEffectsHappened;
  177. Check(RolByte(0, u8_SideEffects), 0); CheckSideEffectsHappened;
  178. Check(RorByte($ff, u8_SideEffects), $ff); CheckSideEffectsHappened;
  179. Check(RolByte($ff, u8_SideEffects), $ff); CheckSideEffectsHappened;
  180. {$endif FPC_HAS_INTERNAL_ROX_BYTE}
  181. {$ifdef FPC_HAS_INTERNAL_ROX_WORD}
  182. Check(RorWord(0, u8_SideEffects), 0); CheckNoSideEffectsHappened;
  183. Check(RolWord(0, u8_SideEffects), 0); CheckNoSideEffectsHappened;
  184. Check(RorWord($ffff, u8_SideEffects), $ffff); CheckNoSideEffectsHappened;
  185. Check(RolWord($ffff, u8_SideEffects), $ffff); CheckNoSideEffectsHappened;
  186. {$else FPC_HAS_INTERNAL_ROX_WORD}
  187. Check(RorWord(0, u8_SideEffects), 0); CheckSideEffectsHappened;
  188. Check(RolWord(0, u8_SideEffects), 0); CheckSideEffectsHappened;
  189. Check(RorWord($ffff, u8_SideEffects), $ffff); CheckSideEffectsHappened;
  190. Check(RolWord($ffff, u8_SideEffects), $ffff); CheckSideEffectsHappened;
  191. {$endif FPC_HAS_INTERNAL_ROX_WORD}
  192. {$ifdef FPC_HAS_INTERNAL_ROX_DWORD}
  193. Check(RorDWord(0, u8_SideEffects), 0); CheckNoSideEffectsHappened;
  194. Check(RolDWord(0, u8_SideEffects), 0); CheckNoSideEffectsHappened;
  195. Check(RorDWord($ffffffff, u8_SideEffects), $ffffffff); CheckNoSideEffectsHappened;
  196. Check(RolDWord($ffffffff, u8_SideEffects), $ffffffff); CheckNoSideEffectsHappened;
  197. {$else FPC_HAS_INTERNAL_ROX_DWORD}
  198. Check(RorDWord(0, u8_SideEffects), 0); CheckSideEffectsHappened;
  199. Check(RolDWord(0, u8_SideEffects), 0); CheckSideEffectsHappened;
  200. Check(RorDWord($ffffffff, u8_SideEffects), $ffffffff); CheckSideEffectsHappened;
  201. Check(RolDWord($ffffffff, u8_SideEffects), $ffffffff); CheckSideEffectsHappened;
  202. {$endif FPC_HAS_INTERNAL_ROX_DWORD}
  203. {$ifdef FPC_HAS_INTERNAL_ROX_QWORD}
  204. Check(RorQWord(0, u8_SideEffects), 0); CheckNoSideEffectsHappened;
  205. Check(RolQWord(0, u8_SideEffects), 0); CheckNoSideEffectsHappened;
  206. Check(RorQWord(QWord($ffffffffffffffff), u8_SideEffects), QWord($ffffffffffffffff)); CheckNoSideEffectsHappened;
  207. Check(RolQWord(QWord($ffffffffffffffff), u8_SideEffects), QWord($ffffffffffffffff)); CheckNoSideEffectsHappened;
  208. {$else FPC_HAS_INTERNAL_ROX_QWORD}
  209. Check(RorQWord(0, u8_SideEffects), 0); CheckSideEffectsHappened;
  210. Check(RolQWord(0, u8_SideEffects), 0); CheckSideEffectsHappened;
  211. Check(RorQWord(QWord($ffffffffffffffff), u8_SideEffects), QWord($ffffffffffffffff)); CheckSideEffectsHappened;
  212. Check(RolQWord(QWord($ffffffffffffffff), u8_SideEffects), QWord($ffffffffffffffff)); CheckSideEffectsHappened;
  213. {$endif FPC_HAS_INTERNAL_ROX_QWORD}
  214. end;
  215. Writeln('Ok!');
  216. end.