Так много бесполезных комментариев ...
Кажется, это ошибка в анализаторе псевдонимов Clang.Если вы измените тип с v2
на short
, компилятор удачно удалит его из цикла на основе правил псевдонимов на основе типов:
for.body: ; preds = %for.inc, %for.body.lr.ph
%i.09 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.inc ]
%ptr1.addr.08 = phi i32* [ %ptr1, %for.body.lr.ph ], [ %ptr1.addr.1, %for.inc ]
%1 = load i32, i32* %ptr1.addr.08, align 4, !tbaa !5
%cmp1 = icmp eq i32 %1, %conv
br i1 %cmp1, label %if.then, label %if.else
Но с оригинальным циклом вы получите одинаковый набор псевдонимов для обеих ссылок на памятьВот почему средний класс не может его оптимизировать:
%i.08 = phi i32 [ %inc, %for.inc ], [ 0, %for.body.preheader ]
%ptr1.addr.07 = phi i32* [ %ptr1.addr.1, %for.inc ], [ %ptr1, %for.body.preheader ]
%0 = load i32, i32* %ptr1.addr.07, align 4, !tbaa !1
%1 = load i32, i32* %v2, align 4, !tbaa !1
%cmp1 = icmp eq i32 %0, %1
br i1 %cmp1, label %if.then, label %if.else
Обратите внимание на !tbaa !1
, прикрепленный к обоим ссылкам на память, что означает, что компилятор не может различить память, к которой обращается один из них.Похоже, что restrict
аннотация была потеряна по пути ...
Я рекомендую вам воспроизвести это с последним Clang и сообщить об ошибке в LLVM Bugzilla (обязательно cc HalФинкель).