diff options
Diffstat (limited to 'llvm/test')
-rw-r--r-- | llvm/test/CodeGen/AArch64/combine-comparisons-by-cse.ll | 349 |
1 files changed, 349 insertions, 0 deletions
diff --git a/llvm/test/CodeGen/AArch64/combine-comparisons-by-cse.ll b/llvm/test/CodeGen/AArch64/combine-comparisons-by-cse.ll new file mode 100644 index 00000000000..b8bce3f7b13 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/combine-comparisons-by-cse.ll @@ -0,0 +1,349 @@ +; RUN: llc < %s -march=aarch64 -mtriple=aarch64-linux-gnu | FileCheck %s + +; marked as external to prevent possible optimizations +@a = external global i32 +@b = external global i32 +@c = external global i32 +@d = external global i32 + +; (a > 10 && b == c) || (a >= 10 && b == d) +define i32 @combine_gt_ge_10() #0 { +; CHECK-LABEL: combine_gt_ge_10 +; CHECK: cmp +; CHECK: b.le +; CHECK: ret +; CHECK-NOT: cmp +; CHECK: b.lt +entry: + %0 = load i32* @a, align 4 + %cmp = icmp sgt i32 %0, 10 + br i1 %cmp, label %land.lhs.true, label %lor.lhs.false + +land.lhs.true: ; preds = %entry + %1 = load i32* @b, align 4 + %2 = load i32* @c, align 4 + %cmp1 = icmp eq i32 %1, %2 + br i1 %cmp1, label %return, label %land.lhs.true3 + +lor.lhs.false: ; preds = %entry + %cmp2 = icmp sgt i32 %0, 9 + br i1 %cmp2, label %land.lhs.true3, label %if.end + +land.lhs.true3: ; preds = %lor.lhs.false, %land.lhs.true + %3 = load i32* @b, align 4 + %4 = load i32* @d, align 4 + %cmp4 = icmp eq i32 %3, %4 + br i1 %cmp4, label %return, label %if.end + +if.end: ; preds = %land.lhs.true3, %lor.lhs.false + br label %return + +return: ; preds = %if.end, %land.lhs.true3, %land.lhs.true + %retval.0 = phi i32 [ 0, %if.end ], [ 1, %land.lhs.true3 ], [ 1, %land.lhs.true ] + ret i32 %retval.0 +} + +; (a > 5 && b == c) || (a < 5 && b == d) +define i32 @combine_gt_lt_5() #0 { +; CHECK-LABEL: combine_gt_lt_5 +; CHECK: cmp +; CHECK: b.le +; CHECK: ret +; CHECK-NOT: cmp +; CHECK: b.ge +entry: + %0 = load i32* @a, align 4 + %cmp = icmp sgt i32 %0, 5 + br i1 %cmp, label %land.lhs.true, label %lor.lhs.false + +land.lhs.true: ; preds = %entry + %1 = load i32* @b, align 4 + %2 = load i32* @c, align 4 + %cmp1 = icmp eq i32 %1, %2 + br i1 %cmp1, label %return, label %if.end + +lor.lhs.false: ; preds = %entry + %cmp2 = icmp slt i32 %0, 5 + br i1 %cmp2, label %land.lhs.true3, label %if.end + +land.lhs.true3: ; preds = %lor.lhs.false + %3 = load i32* @b, align 4 + %4 = load i32* @d, align 4 + %cmp4 = icmp eq i32 %3, %4 + br i1 %cmp4, label %return, label %if.end + +if.end: ; preds = %land.lhs.true3, %lor.lhs.false, %land.lhs.true + br label %return + +return: ; preds = %if.end, %land.lhs.true3, %land.lhs.true + %retval.0 = phi i32 [ 0, %if.end ], [ 1, %land.lhs.true3 ], [ 1, %land.lhs.true ] + ret i32 %retval.0 +} + +; (a < 5 && b == c) || (a <= 5 && b == d) +define i32 @combine_lt_ge_5() #0 { +; CHECK-LABEL: combine_lt_ge_5 +; CHECK: cmp +; CHECK: b.ge +; CHECK: ret +; CHECK-NOT: cmp +; CHECK: b.gt +entry: + %0 = load i32* @a, align 4 + %cmp = icmp slt i32 %0, 5 + br i1 %cmp, label %land.lhs.true, label %lor.lhs.false + +land.lhs.true: ; preds = %entry + %1 = load i32* @b, align 4 + %2 = load i32* @c, align 4 + %cmp1 = icmp eq i32 %1, %2 + br i1 %cmp1, label %return, label %land.lhs.true3 + +lor.lhs.false: ; preds = %entry + %cmp2 = icmp slt i32 %0, 6 + br i1 %cmp2, label %land.lhs.true3, label %if.end + +land.lhs.true3: ; preds = %lor.lhs.false, %land.lhs.true + %3 = load i32* @b, align 4 + %4 = load i32* @d, align 4 + %cmp4 = icmp eq i32 %3, %4 + br i1 %cmp4, label %return, label %if.end + +if.end: ; preds = %land.lhs.true3, %lor.lhs.false + br label %return + +return: ; preds = %if.end, %land.lhs.true3, %land.lhs.true + %retval.0 = phi i32 [ 0, %if.end ], [ 1, %land.lhs.true3 ], [ 1, %land.lhs.true ] + ret i32 %retval.0 +} + +; (a < 5 && b == c) || (a > 5 && b == d) +define i32 @combine_lt_gt_5() #0 { +; CHECK-LABEL: combine_lt_gt_5 +; CHECK: cmp +; CHECK: b.ge +; CHECK: ret +; CHECK-NOT: cmp +; CHECK: b.le +entry: + %0 = load i32* @a, align 4 + %cmp = icmp slt i32 %0, 5 + br i1 %cmp, label %land.lhs.true, label %lor.lhs.false + +land.lhs.true: ; preds = %entry + %1 = load i32* @b, align 4 + %2 = load i32* @c, align 4 + %cmp1 = icmp eq i32 %1, %2 + br i1 %cmp1, label %return, label %if.end + +lor.lhs.false: ; preds = %entry + %cmp2 = icmp sgt i32 %0, 5 + br i1 %cmp2, label %land.lhs.true3, label %if.end + +land.lhs.true3: ; preds = %lor.lhs.false + %3 = load i32* @b, align 4 + %4 = load i32* @d, align 4 + %cmp4 = icmp eq i32 %3, %4 + br i1 %cmp4, label %return, label %if.end + +if.end: ; preds = %land.lhs.true3, %lor.lhs.false, %land.lhs.true + br label %return + +return: ; preds = %if.end, %land.lhs.true3, %land.lhs.true + %retval.0 = phi i32 [ 0, %if.end ], [ 1, %land.lhs.true3 ], [ 1, %land.lhs.true ] + ret i32 %retval.0 +} + +; (a > -5 && b == c) || (a < -5 && b == d) +define i32 @combine_gt_lt_n5() #0 { +; CHECK-LABEL: combine_gt_lt_n5 +; CHECK: cmn +; CHECK: b.le +; CHECK: ret +; CHECK-NOT: cmn +; CHECK: b.ge +entry: + %0 = load i32* @a, align 4 + %cmp = icmp sgt i32 %0, -5 + br i1 %cmp, label %land.lhs.true, label %lor.lhs.false + +land.lhs.true: ; preds = %entry + %1 = load i32* @b, align 4 + %2 = load i32* @c, align 4 + %cmp1 = icmp eq i32 %1, %2 + br i1 %cmp1, label %return, label %if.end + +lor.lhs.false: ; preds = %entry + %cmp2 = icmp slt i32 %0, -5 + br i1 %cmp2, label %land.lhs.true3, label %if.end + +land.lhs.true3: ; preds = %lor.lhs.false + %3 = load i32* @b, align 4 + %4 = load i32* @d, align 4 + %cmp4 = icmp eq i32 %3, %4 + br i1 %cmp4, label %return, label %if.end + +if.end: ; preds = %land.lhs.true3, %lor.lhs.false, %land.lhs.true + br label %return + +return: ; preds = %if.end, %land.lhs.true3, %land.lhs.true + %retval.0 = phi i32 [ 0, %if.end ], [ 1, %land.lhs.true3 ], [ 1, %land.lhs.true ] + ret i32 %retval.0 +} + +; (a < -5 && b == c) || (a > -5 && b == d) +define i32 @combine_lt_gt_n5() #0 { +; CHECK-LABEL: combine_lt_gt_n5 +; CHECK: cmn +; CHECK: b.ge +; CHECK: ret +; CHECK-NOT: cmn +; CHECK: b.le +entry: + %0 = load i32* @a, align 4 + %cmp = icmp slt i32 %0, -5 + br i1 %cmp, label %land.lhs.true, label %lor.lhs.false + +land.lhs.true: ; preds = %entry + %1 = load i32* @b, align 4 + %2 = load i32* @c, align 4 + %cmp1 = icmp eq i32 %1, %2 + br i1 %cmp1, label %return, label %if.end + +lor.lhs.false: ; preds = %entry + %cmp2 = icmp sgt i32 %0, -5 + br i1 %cmp2, label %land.lhs.true3, label %if.end + +land.lhs.true3: ; preds = %lor.lhs.false + %3 = load i32* @b, align 4 + %4 = load i32* @d, align 4 + %cmp4 = icmp eq i32 %3, %4 + br i1 %cmp4, label %return, label %if.end + +if.end: ; preds = %land.lhs.true3, %lor.lhs.false, %land.lhs.true + br label %return + +return: ; preds = %if.end, %land.lhs.true3, %land.lhs.true + %retval.0 = phi i32 [ 0, %if.end ], [ 1, %land.lhs.true3 ], [ 1, %land.lhs.true ] + ret i32 %retval.0 +} + +%struct.Struct = type { i64, i64 } + +@glob = internal unnamed_addr global %struct.Struct* null, align 8 + +declare %struct.Struct* @Update(%struct.Struct*) #1 + +; no checks for this case, it just should be processed without errors +define void @combine_non_adjacent_cmp_br(%struct.Struct* nocapture readonly %hdCall) #0 { +entry: + %size = getelementptr inbounds %struct.Struct* %hdCall, i64 0, i32 0 + %0 = load i64* %size, align 8 + br label %land.rhs + +land.rhs: + %rp.06 = phi i64 [ %0, %entry ], [ %sub, %while.body ] + %1 = load i64* inttoptr (i64 24 to i64*), align 8 + %cmp2 = icmp sgt i64 %1, 0 + br i1 %cmp2, label %while.body, label %while.end + +while.body: + %2 = load %struct.Struct** @glob, align 8 + %call = tail call %struct.Struct* @Update(%struct.Struct* %2) #2 + %sub = add nsw i64 %rp.06, -2 + %cmp = icmp slt i64 %0, %rp.06 + br i1 %cmp, label %land.rhs, label %while.end + +while.end: + ret void +} + +; undefined external to prevent possible optimizations +declare void @do_something() #1 + +define i32 @do_nothing_if_resultant_opcodes_would_differ() #0 { +; CHECK-LABEL: do_nothing_if_resultant_opcodes_would_differ +; CHECK: cmn +; CHECK: b.gt +; CHECK: cmp +; CHECK: b.gt +entry: + %0 = load i32* @a, align 4 + %cmp4 = icmp slt i32 %0, -1 + br i1 %cmp4, label %while.body.preheader, label %while.end + +while.body.preheader: ; preds = %entry + br label %while.body + +while.body: ; preds = %while.body, %while.body.preheader + %i.05 = phi i32 [ %inc, %while.body ], [ %0, %while.body.preheader ] + tail call void @do_something() #2 + %inc = add nsw i32 %i.05, 1 + %cmp = icmp slt i32 %i.05, 0 + br i1 %cmp, label %while.body, label %while.cond.while.end_crit_edge + +while.cond.while.end_crit_edge: ; preds = %while.body + %.pre = load i32* @a, align 4 + br label %while.end + +while.end: ; preds = %while.cond.while.end_crit_edge, %entry + %1 = phi i32 [ %.pre, %while.cond.while.end_crit_edge ], [ %0, %entry ] + %cmp1 = icmp slt i32 %1, 2 + br i1 %cmp1, label %land.lhs.true, label %if.end + +land.lhs.true: ; preds = %while.end + %2 = load i32* @b, align 4 + %3 = load i32* @d, align 4 + %cmp2 = icmp eq i32 %2, %3 + br i1 %cmp2, label %return, label %if.end + +if.end: ; preds = %land.lhs.true, %while.end + br label %return + +return: ; preds = %if.end, %land.lhs.true + %retval.0 = phi i32 [ 0, %if.end ], [ 123, %land.lhs.true ] + ret i32 %retval.0 +} + +define i32 @do_nothing_if_compares_can_not_be_adjusted_to_each_other() #0 { +; CHECK-LABEL: do_nothing_if_compares_can_not_be_adjusted_to_each_other +; CHECK: cmp +; CHECK: b.gt +; CHECK: cmn +; CHECK: b.lt +entry: + %0 = load i32* @a, align 4 + %cmp4 = icmp slt i32 %0, 1 + br i1 %cmp4, label %while.body.preheader, label %while.end + +while.body.preheader: ; preds = %entry + br label %while.body + +while.body: ; preds = %while.body, %while.body.preheader + %i.05 = phi i32 [ %inc, %while.body ], [ %0, %while.body.preheader ] + tail call void @do_something() #2 + %inc = add nsw i32 %i.05, 1 + %cmp = icmp slt i32 %i.05, 0 + br i1 %cmp, label %while.body, label %while.end.loopexit + +while.end.loopexit: ; preds = %while.body + br label %while.end + +while.end: ; preds = %while.end.loopexit, %entry + %1 = load i32* @c, align 4 + %cmp1 = icmp sgt i32 %1, -3 + br i1 %cmp1, label %land.lhs.true, label %if.end + +land.lhs.true: ; preds = %while.end + %2 = load i32* @b, align 4 + %3 = load i32* @d, align 4 + %cmp2 = icmp eq i32 %2, %3 + br i1 %cmp2, label %return, label %if.end + +if.end: ; preds = %land.lhs.true, %while.end + br label %return + +return: ; preds = %if.end, %land.lhs.true + %retval.0 = phi i32 [ 0, %if.end ], [ 123, %land.lhs.true ] + ret i32 %retval.0 +} |