diff --git a/llvm/test/Transforms/InstCombine/icmp-or-x-with-x.ll b/llvm/test/Transforms/InstCombine/icmp-or-x-with-x.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/icmp-or-x-with-x.ll @@ -0,0 +1,108 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2 +; RUN: opt < %s -passes=instcombine -S | FileCheck %s + +declare void @use.i8(i8) +define i1 @fold_or_eq(i8 %x) { +; CHECK-LABEL: define i1 @fold_or_eq +; CHECK-SAME: (i8 [[X:%.*]]) { +; CHECK-NEXT: [[XO:%.*]] = or i8 [[X]], 123 +; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[XO]], [[X]] +; CHECK-NEXT: ret i1 [[R]] +; + %xo = or i8 %x, 123 + %r = icmp eq i8 %xo, %x + ret i1 %r +} + +define <2 x i1> @fold_or_ne(<2 x i8> %xx) { +; CHECK-LABEL: define <2 x i1> @fold_or_ne +; CHECK-SAME: (<2 x i8> [[XX:%.*]]) { +; CHECK-NEXT: [[X:%.*]] = mul <2 x i8> [[XX]], [[XX]] +; CHECK-NEXT: [[XO:%.*]] = or <2 x i8> [[X]], +; CHECK-NEXT: [[R:%.*]] = icmp ne <2 x i8> [[X]], [[XO]] +; CHECK-NEXT: ret <2 x i1> [[R]] +; + %x = mul <2 x i8> %xx, %xx + %xo = or <2 x i8> %x, + %r = icmp ne <2 x i8> %x, %xo + ret <2 x i1> %r +} + +define i1 @fold_or_eq_fail_multiuse(i8 %x) { +; CHECK-LABEL: define i1 @fold_or_eq_fail_multiuse +; CHECK-SAME: (i8 [[X:%.*]]) { +; CHECK-NEXT: [[XO:%.*]] = or i8 [[X]], 123 +; CHECK-NEXT: call void @use.i8(i8 [[XO]]) +; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[XO]], [[X]] +; CHECK-NEXT: ret i1 [[R]] +; + %xo = or i8 %x, 123 + call void @use.i8(i8 %xo) + %r = icmp eq i8 %xo, %x + ret i1 %r +} + +define i1 @fold_or_slt_fail(i8 %x) { +; CHECK-LABEL: define i1 @fold_or_slt_fail +; CHECK-SAME: (i8 [[X:%.*]]) { +; CHECK-NEXT: [[XO:%.*]] = or i8 [[X]], 123 +; CHECK-NEXT: call void @use.i8(i8 [[XO]]) +; CHECK-NEXT: ret i1 false +; + %xo = or i8 %x, 123 + call void @use.i8(i8 %xo) + %r = icmp slt i8 %xo, %x + ret i1 %r +} + +define <2 x i1> @fold_or_ne_fail_wrong_args(<2 x i8> %xx) { +; CHECK-LABEL: define <2 x i1> @fold_or_ne_fail_wrong_args +; CHECK-SAME: (<2 x i8> [[XX:%.*]]) { +; CHECK-NEXT: [[X:%.*]] = mul <2 x i8> [[XX]], [[XX]] +; CHECK-NEXT: [[XO:%.*]] = or <2 x i8> [[X]], +; CHECK-NEXT: [[R:%.*]] = icmp ne <2 x i8> [[XO]], [[XX]] +; CHECK-NEXT: ret <2 x i1> [[R]] +; + %x = mul <2 x i8> %xx, %xx + %xo = or <2 x i8> %x, + %r = icmp ne <2 x i8> %xx, %xo + ret <2 x i1> %r +} + +define <2 x i1> @fold_or_ne_fail_non_const(<2 x i8> %xx) { +; CHECK-LABEL: define <2 x i1> @fold_or_ne_fail_non_const +; CHECK-SAME: (<2 x i8> [[XX:%.*]]) { +; CHECK-NEXT: [[X:%.*]] = mul <2 x i8> [[XX]], [[XX]] +; CHECK-NEXT: [[XO:%.*]] = or <2 x i8> [[X]], [[XX]] +; CHECK-NEXT: [[R:%.*]] = icmp ne <2 x i8> [[X]], [[XO]] +; CHECK-NEXT: ret <2 x i1> [[R]] +; + %x = mul <2 x i8> %xx, %xx + %xo = or <2 x i8> %x, %xx + %r = icmp ne <2 x i8> %x, %xo + ret <2 x i1> %r +} + +define <2 x i1> @fold_or_ne_fail_has_undef(<2 x i8> %x) { +; CHECK-LABEL: define <2 x i1> @fold_or_ne_fail_has_undef +; CHECK-SAME: (<2 x i8> [[X:%.*]]) { +; CHECK-NEXT: [[XO:%.*]] = or <2 x i8> [[X]], +; CHECK-NEXT: [[R:%.*]] = icmp ne <2 x i8> [[XO]], [[X]] +; CHECK-NEXT: ret <2 x i1> [[R]] +; + %xo = or <2 x i8> %x, + %r = icmp ne <2 x i8> %x, %xo + ret <2 x i1> %r +} + +define <2 x i1> @fold_or_eq_with_poison(<2 x i8> %x) { +; CHECK-LABEL: define <2 x i1> @fold_or_eq_with_poison +; CHECK-SAME: (<2 x i8> [[X:%.*]]) { +; CHECK-NEXT: [[XO:%.*]] = or <2 x i8> [[X]], +; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i8> [[XO]], [[X]] +; CHECK-NEXT: ret <2 x i1> [[R]] +; + %xo = or <2 x i8> %x, + %r = icmp eq <2 x i8> %x, %xo + ret <2 x i1> %r +}