aboutsummaryrefslogtreecommitdiffstats
path: root/test/Transforms/InstCombine
diff options
context:
space:
mode:
authorQuentin Colombet <qcolombet@apple.com>2013-09-09 20:56:48 +0000
committerQuentin Colombet <qcolombet@apple.com>2013-09-09 20:56:48 +0000
commit2c6ef1c4339c2961745bc3747753e4f2d23ee7c6 (patch)
treedf73fff89d0e603ab6c4937e31f4aef0ac0e0825 /test/Transforms/InstCombine
parent0b9ba182a7a91ad2ea7ef8486a4107c680650927 (diff)
downloadexternal_llvm-2c6ef1c4339c2961745bc3747753e4f2d23ee7c6.zip
external_llvm-2c6ef1c4339c2961745bc3747753e4f2d23ee7c6.tar.gz
external_llvm-2c6ef1c4339c2961745bc3747753e4f2d23ee7c6.tar.bz2
[InstCombiner] Expose opportunities to merge subtract and comparison.
Several architectures use the same instruction to perform both a comparison and a subtract. The instruction selection framework does not allow to consider different basic blocks to expose such fusion opportunities. Therefore, these instructions are “merged” by CSE at MI IR level. To increase the likelihood of CSE to apply in such situation, we reorder the operands of the comparison, when they have the same complexity, so that they matches the order of the most frequent subtract. E.g., icmp A, B ... sub B, A <rdar://problem/14514580> git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@190352 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/Transforms/InstCombine')
-rw-r--r--test/Transforms/InstCombine/icmp.ll65
1 files changed, 65 insertions, 0 deletions
diff --git a/test/Transforms/InstCombine/icmp.ll b/test/Transforms/InstCombine/icmp.ll
index 33636c4..bd8128f 100644
--- a/test/Transforms/InstCombine/icmp.ll
+++ b/test/Transforms/InstCombine/icmp.ll
@@ -1271,3 +1271,68 @@ define i1 @icmp_sub_-1_X_uge_4(i32 %X) {
%cmp = icmp uge i32 %sub, 4
ret i1 %cmp
}
+
+; CHECK-LABEL: @icmp_swap_operands_for_cse
+; CHECK: [[CMP:%[a-z0-9]+]] = icmp ult i32 %X, %Y
+; CHECK-NEXT: br i1 [[CMP]], label %true, label %false
+; CHECK: ret i1
+define i1 @icmp_swap_operands_for_cse(i32 %X, i32 %Y) {
+entry:
+ %sub = sub i32 %X, %Y
+ %cmp = icmp ugt i32 %Y, %X
+ br i1 %cmp, label %true, label %false
+true:
+ %restrue = trunc i32 %sub to i1
+ br label %end
+false:
+ %shift = lshr i32 %sub, 4
+ %resfalse = trunc i32 %shift to i1
+ br label %end
+end:
+ %res = phi i1 [%restrue, %true], [%resfalse, %false]
+ ret i1 %res
+}
+
+; CHECK-LABEL: @icmp_swap_operands_for_cse2
+; CHECK: [[CMP:%[a-z0-9]+]] = icmp ult i32 %X, %Y
+; CHECK-NEXT: br i1 [[CMP]], label %true, label %false
+; CHECK: ret i1
+define i1 @icmp_swap_operands_for_cse2(i32 %X, i32 %Y) {
+entry:
+ %cmp = icmp ugt i32 %Y, %X
+ br i1 %cmp, label %true, label %false
+true:
+ %sub = sub i32 %X, %Y
+ %sub1 = sub i32 %X, %Y
+ %add = add i32 %sub, %sub1
+ %restrue = trunc i32 %add to i1
+ br label %end
+false:
+ %sub2 = sub i32 %Y, %X
+ %resfalse = trunc i32 %sub2 to i1
+ br label %end
+end:
+ %res = phi i1 [%restrue, %true], [%resfalse, %false]
+ ret i1 %res
+}
+
+; CHECK-LABEL: @icmp_do_not_swap_operands_for_cse
+; CHECK: [[CMP:%[a-z0-9]+]] = icmp ugt i32 %Y, %X
+; CHECK-NEXT: br i1 [[CMP]], label %true, label %false
+; CHECK: ret i1
+define i1 @icmp_do_not_swap_operands_for_cse(i32 %X, i32 %Y) {
+entry:
+ %cmp = icmp ugt i32 %Y, %X
+ br i1 %cmp, label %true, label %false
+true:
+ %sub = sub i32 %X, %Y
+ %restrue = trunc i32 %sub to i1
+ br label %end
+false:
+ %sub2 = sub i32 %Y, %X
+ %resfalse = trunc i32 %sub2 to i1
+ br label %end
+end:
+ %res = phi i1 [%restrue, %true], [%resfalse, %false]
+ ret i1 %res
+}