こういうソースコードをclangすると…
void example03(char *a, char *b, char *c){
int i = 0;
while(1)
{
c[i] = a[i] * b[i];
i++;
if(i>=100) break;
}
}
デフォルトの最適化でつぎのようになる。
define dso_local void @example03(ptr noundef %0, ptr noundef %1, ptr noundef %2) #0 {
%4 = alloca ptr, align 4
%5 = alloca ptr, align 4
%6 = alloca ptr, align 4
%7 = alloca i32, align 4
store ptr %0, ptr %4, align 4
store ptr %1, ptr %5, align 4
store ptr %2, ptr %6, align 4
store i32 0, ptr %7, align 4
br label %8
8: ; preds = %3, %29
%9 = load ptr, ptr %4, align 4
%10 = load i32, ptr %7, align 4
%11 = getelementptr inbounds i8, ptr %9, i32 %10
%12 = load i8, ptr %11, align 1
%13 = sext i8 %12 to i32
%14 = load ptr, ptr %5, align 4
%15 = load i32, ptr %7, align 4
%16 = getelementptr inbounds i8, ptr %14, i32 %15
%17 = load i8, ptr %16, align 1
%18 = sext i8 %17 to i32
%19 = mul nsw i32 %13, %18
%20 = trunc i32 %19 to i8
%21 = load ptr, ptr %6, align 4
%22 = load i32, ptr %7, align 4
%23 = getelementptr inbounds i8, ptr %21, i32 %22
store i8 %20, ptr %23, align 1
%24 = load i32, ptr %7, align 4
%25 = add nsw i32 %24, 1
store i32 %25, ptr %7, align 4
%26 = load i32, ptr %7, align 4
%27 = icmp sge i32 %26, 100
br i1 %27, label %28, label %29
28: ; preds = %8
br label %30
29: ; preds = %8
br label %8
30: ; preds = %28
ret void
}
-O3
にするとつぎのようになる。
define dso_local void @example03(ptr nocapture noundef readonly %0, ptr nocapture noundef readonly %1, ptr nocapture noundef writeonly %2) local_unnamed_addr #0 {
br label %4
4: ; preds = %4, %3
%5 = phi i32 [ 0, %3 ], [ %33, %4 ]
%6 = getelementptr inbounds i8, ptr %0, i32 %5
%7 = load i8, ptr %6, align 1, !tbaa !6
%8 = getelementptr inbounds i8, ptr %1, i32 %5
%9 = load i8, ptr %8, align 1, !tbaa !6
%10 = mul i8 %9, %7
%11 = getelementptr inbounds i8, ptr %2, i32 %5
store i8 %10, ptr %11, align 1, !tbaa !6
%12 = or disjoint i32 %5, 1
%13 = getelementptr inbounds i8, ptr %0, i32 %12
%14 = load i8, ptr %13, align 1, !tbaa !6
%15 = getelementptr inbounds i8, ptr %1, i32 %12
%16 = load i8, ptr %15, align 1, !tbaa !6
%17 = mul i8 %16, %14
%18 = getelementptr inbounds i8, ptr %2, i32 %12
store i8 %17, ptr %18, align 1, !tbaa !6
%19 = or disjoint i32 %5, 2
%20 = getelementptr inbounds i8, ptr %0, i32 %19
%21 = load i8, ptr %20, align 1, !tbaa !6
%22 = getelementptr inbounds i8, ptr %1, i32 %19
%23 = load i8, ptr %22, align 1, !tbaa !6
%24 = mul i8 %23, %21
%25 = getelementptr inbounds i8, ptr %2, i32 %19
store i8 %24, ptr %25, align 1, !tbaa !6
%26 = or disjoint i32 %5, 3
%27 = getelementptr inbounds i8, ptr %0, i32 %26
%28 = load i8, ptr %27, align 1, !tbaa !6
%29 = getelementptr inbounds i8, ptr %1, i32 %26
%30 = load i8, ptr %29, align 1, !tbaa !6
%31 = mul i8 %30, %28
%32 = getelementptr inbounds i8, ptr %2, i32 %26
store i8 %31, ptr %32, align 1, !tbaa !6
%33 = add nuw nsw i32 %5, 4
%34 = icmp eq i32 %33, 100
br i1 %34, label %35, label %4, !llvm.loop !9
35: ; preds = %4
ret void
}