[PATCH] D93850: [InstCombine] Rewrite (switch (zext X)) as (switch X).
Chenguang Wang via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Sun Dec 27 22:21:14 PST 2020
wecing added a comment.
Here is a longer example showing the improvements of this change:
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
define i32 @f1({ i32, i32 }* %x, { i32, i32 }* %y) {
start:
%0 = getelementptr inbounds { i32, i32 }, { i32, i32 }* %x, i64 0, i32 0
%1 = load i32, i32* %0, align 4, !range !5
%_1 = zext i32 %1 to i64
%2 = getelementptr inbounds { i32, i32 }, { i32, i32 }* %y, i64 0, i32 0
%3 = load i32, i32* %2, align 4, !range !5
%_3 = zext i32 %3 to i64
%cond1 = icmp eq i64 %_1, %_3
br i1 %cond1, label %bb1, label %bb41
bb1:
switch i64 %_1, label %bb41 [
i64 0, label %bb2
i64 1, label %bb5
i64 2, label %bb7
i64 3, label %bb9
]
bb2:
ret i32 100
bb5:
ret i32 101
bb7:
ret i32 102
bb9:
%4 = getelementptr inbounds { i32, i32 }, { i32, i32 }* %y, i64 0, i32 0
%5 = load i32, i32* %4, align 4, !range !5
%_5 = zext i32 %5 to i64
%cond2 = icmp eq i64 %_5, 3
br i1 %cond2, label %bb10, label %bb11
bb10:
ret i32 1001
bb11:
ret i32 1002
bb41:
unreachable
}
!5 = !{i32 0, i32 4}
Without this patch, `opt -S -O3 no.ll` produces:
define i32 @f1({ i32, i32 }* nocapture readonly %x, { i32, i32 }* nocapture readonly %y) local_unnamed_addr #0 {
start:
%0 = getelementptr inbounds { i32, i32 }, { i32, i32 }* %x, i64 0, i32 0
%1 = load i32, i32* %0, align 4, !range !0
%_1 = zext i32 %1 to i64
%2 = getelementptr inbounds { i32, i32 }, { i32, i32 }* %y, i64 0, i32 0
%3 = load i32, i32* %2, align 4, !range !0
%cond1 = icmp eq i32 %1, %3
tail call void @llvm.assume(i1 %cond1)
switch i64 %_1, label %bb41 [
i64 0, label %bb2
i64 1, label %bb5
i64 2, label %bb7
i64 3, label %bb9
]
bb2: ; preds = %bb9, %bb7, %bb5, %start
%merge = phi i32 [ 100, %start ], [ 101, %bb5 ], [ 102, %bb7 ], [ %., %bb9 ]
ret i32 %merge
bb5: ; preds = %start
br label %bb2
bb7: ; preds = %start
br label %bb2
bb9: ; preds = %start
%cond2 = icmp eq i32 %1, 3
%. = select i1 %cond2, i32 1001, i32 1002
br label %bb2
bb41: ; preds = %start
unreachable
}
!0 = !{i32 0, i32 4}
Note that the `icmp eq i32 %1, 3` in `bb9` is actually is unnecessary, because in the input, `icmp eq i64 %_1, %_3` from the `start` block must be true.
With this fix, the output becomes:
define i32 @f1({ i32, i32 }* nocapture readonly %x, { i32, i32 }* nocapture readonly %y) local_unnamed_addr #0 {
start:
%0 = getelementptr inbounds { i32, i32 }, { i32, i32 }* %x, i64 0, i32 0
%1 = load i32, i32* %0, align 4, !range !0
%2 = getelementptr inbounds { i32, i32 }, { i32, i32 }* %y, i64 0, i32 0
%3 = load i32, i32* %2, align 4, !range !0
%cond1 = icmp eq i32 %1, %3
tail call void @llvm.assume(i1 %cond1)
switch i32 %1, label %bb41 [
i32 0, label %bb2
i32 1, label %bb5
i32 2, label %bb7
i32 3, label %bb9
]
bb2: ; preds = %bb9, %bb7, %bb5, %start
%merge = phi i32 [ 100, %start ], [ 101, %bb5 ], [ 102, %bb7 ], [ 1001, %bb9 ]
ret i32 %merge
bb5: ; preds = %start
br label %bb2
bb7: ; preds = %start
br label %bb2
bb9: ; preds = %start
br label %bb2
bb41: ; preds = %start
unreachable
}
!0 = !{i32 0, i32 4}
The difference is also reflected in output assembly.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D93850/new/
https://reviews.llvm.org/D93850
More information about the llvm-commits
mailing list