Ho scritto un file cpp illustrato di seguitoL'ottimizzatore LLVM non è in grado di gestire un caso semplice?
int main() {
int a, b;
scanf("%d", &b);
for (int i = 0 ; i < 1000 ; i++) {
a = 0;
if (b > 10)
a = 3;
}
return a;
}
poi ho compilato questo codice da clang con -O3 opzione, il file di output .ll è
define i32 @main() #0 {
entry:
%b = alloca i32, align 4
%call = call i32 (i8*, ...)* @scanf(i8* getelementptr inbounds ([3 x i8]* @.str, i32 0, i32 0), i32* %b)
%0 = load i32* %b, align 4, !tbaa !1
%cmp1 = icmp sgt i32 %0, 10
%. = select i1 %cmp1, i32 3, i32 0
ret i32 %.
}
attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
Questa uscita è buona. L'ottimizzatore LLVM ha rimosso il codice forloop
privo di significato e quindi ha assegnato tre o zero per restituire il valore direttamente.
Ora cerco un altro caso come
int main() {
int a, b;
scanf("%d", &b);
for (int i = 0 ; i < 1000 ; i++) {
a = 0;
if (true) // I modified here only
a = 3;
}
return a;
}
e il file di output è
define i32 @main() #0 {
entry:
%b = alloca i32, align 4
%call = call i32 (i8*, ...)* @scanf(i8* getelementptr inbounds ([3 x i8]* @.str, i32 0, i32 0), i32* %b)
br label %for.cond
for.cond: ; preds = %for.cond, %entry
%a.0 = phi i32 [ 0, %entry ], [ 3, %for.cond ]
%i.0 = phi i32 [ 0, %entry ], [ %inc, %for.cond ]
%inc = add nsw i32 %i.0, 1
%exitcond = icmp eq i32 %inc, 1001
br i1 %exitcond, label %for.end, label %for.cond
for.end: ; preds = %for.cond
ret i32 %a.0
}
attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
Anche se questo codice è più facile da analizzare (ramo è sempre preso), LLVM ottimizzatore non elimina senza senso forloop
Se fossi ottimizzatore, vorrei generare questo codice ottimizzato come
define i32 @main() #0 {
entry:
%b = alloca i32, align 4
%call = call i32 (i8*, ...)* @scanf(i8* getelementptr inbounds ([3 x i8]* @.str, i32 0, i32 0), i32* %b)
ret i32 3
}
Qualcuno può dirmi perché l'ottimizzatore non è in grado di analizzare un codice più semplice?
Suoni come un bug di ottimizzatore per me – MikeMB
quale versione quale piattaforma? – xaxxon
Non sono un dio dell'assemblea, ma questo mi sembra buono (i colori sono belli) https://godbolt.org/g/qxf6jR - Ho incontrato tutte le versioni di clang sul sito e non sono riuscito a riprodurlo con nessuno di loro. – xaxxon