gpt4 book ai didi

objective-c - 为什么 Xcode/LLVM 在为 ARM64 编译时优化此方法返回的变量

转载 作者:太空狗 更新时间:2023-10-30 03:54:00 24 4
gpt4 key购买 nike

This is a known bug and is has been submitted to bugreporter.apple.com under bug id #16040090

NB: This issue only reproducible on a 64-bit (A7) iOS device. If run in the simulator or on a 32-bit device it works fine.

Please note: This bug seems to be fixed in LLVM 5.1, this is the default compiler for Xcode 5.1 (currently in beta).

我有一个方法 -pointValue(见下文),当编译时优化级别设置为 -O0 但使用 -Os(发布版本的默认设置)编译器优化了设置变量 point 的行。 point 用作返回值,因此调用它的任何其他方法都将获得随机值。

可以通过将 points 变量声明为 volatile 来解决此问题。但是,为什么编译器认为它可以删除行设置points?是不是跟我写的方法有关?

- (CGPoint)pointValue
{
ULongLong encodedPoint = [self unsignedLongLongValue];
ULongLong *values = [self splitEncodedInteger:encodedPoint withShift:SHIFT];

//volatile is required to prevent optimising out
volatile CGPoint point = CGPointMake(values[0], values[1]);

free(values); //clean up

return point;
}

注意: -splitEncodedInteger:withShift: 使用 malloc() 创建一个 2 元素数组,该数组被重新调整,然后此内存空闲由被调用者调用。

根据要求,-splitEncodedInteger:withShift:

的代码
- (ULongLong *)splitEncodedInteger:(ULongLong)encocedInteger withShift:(int)shiftValue
{
ULongLong *splitFloats = malloc(sizeof(ULongLong) * 2);

splitFloats[0] = (encocedInteger >> shiftValue);
splitFloats[1] = encocedInteger - ((encocedInteger >> shiftValue) << shiftValue);

return splitFloats;
}

完整 source code的编码类别可以是 found on GitHub .

示例项目

应几位评论者的要求,我创建了一个 simple test project . 然而,即使在设置了所有build设置以匹配原始项目后,我自己 也无法重现该问题。 该错误仅显示在设备上

我唯一能看到不同的是,当项目在完全优化的情况下运行时,LLDB 可以读取一些变量,并尝试将它们打印到控制台,我得到了这个:

(CGSize) size = <no location, value may have been optimized out>

这正是我在失败的项目中得到的结果,但在那种情况下,传递这些“优化过的”变量之一只会提供随机数据(导致创建大量 View [或无法创建])。

下面是分别使用 -O0 和 -Ofast 运行示例应用程序的屏幕截图。

Example app running with -O0 Expanded -O0

使用 -O0(无优化)运行的示例应用程序,您可以看到有关变量的信息

Example app running with -Ofast Expanded -Ofast

使用 -Ofast(完全优化)运行的示例应用,您无法查看变量信息

在设备上运行

这是在优化关闭的情况下运行 ton 设备时的输出:

2014-02-10 11:36:00.771 optimisation-bug[461:60b] *** Compiling with no optmisations, the code should work as expected ***
2014-02-10 11:36:00.773 optimisation-bug[461:60b] encodedRect: 50332672
2014-02-10 11:36:00.774 optimisation-bug[461:60b] encodedSize: 45089712
2014-02-10 11:36:00.775 optimisation-bug[461:60b] encodePoint: 2621480
2014-02-10 11:36:05.629 optimisation-bug[461:60b] rect: {{0, 0}, {768, 1024}}
2014-02-10 11:36:06.099 optimisation-bug[461:60b] size: {688, 944}
2014-02-10 11:36:06.101 optimisation-bug[461:60b] point: 40.000000, 40.000000
2014-02-10 11:36:06.103 optimisation-bug[461:60b] DONE

这是在完全优化的设备上运行时的输出:

2014-02-10 11:44:53.975 optimisation-bug[471:60b] >>> Compiling with -Os optmisations, the code should *NOT* work as expected <<<
2014-02-10 11:44:53.977 optimisation-bug[471:60b] encodedRect: 50332672
2014-02-10 11:44:53.977 optimisation-bug[471:60b] encodedSize: 45089712
2014-02-10 11:44:53.978 optimisation-bug[471:60b] encodePoint: 2621480
2014-02-10 11:44:58.176 optimisation-bug[471:60b] rect: {{1.3464973428307575e+19, 6174053600}, {1.3464973428307575e+19, 1.2554206452792682e+58}}
2014-02-10 11:44:58.178 optimisation-bug[471:60b] size: {1.3464973428307575e+19, 6174053568}
2014-02-10 11:44:58.180 optimisation-bug[471:60b] point: 13464973428307574784.000000, 6174053568.000000
2014-02-10 11:44:58.182 optimisation-bug[471:60b] DONE

最佳答案

这个问题似乎是 arm64 编译器中的一个错误; armv7(s) 和 x86(模拟器)运行代码没有问题。

- (CGPoint)pointValue
{
ULongLong encodedPoint = [self unsignedLongLongValue];
ULongLong *values = [self splitEncodedInteger:encodedPoint withShift:SHIFT];

//volatile is required to prevent optimising out
/*volatile*/ CGPoint point = CGPointMake(values[0], values[1]);

free(values); //clean up

return point;
}

似乎正在发生的事情是 free(values) 行在优化阶段被重新排序并在 CGPointMake(...) 之前运行导致 pointer 返回垃圾值。

感谢Mike Ash , CRDRob Napier .

关于objective-c - 为什么 Xcode/LLVM 在为 ARM64 编译时优化此方法返回的变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21640111/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com