diff --git a/llvm/test/Transforms/InstCombine/icmp-or-of-select-with-zero.ll b/llvm/test/Transforms/InstCombine/icmp-or-of-select-with-zero.ll new file mode 100644 index 000000000000000..45537c2f2fbfee2 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/icmp-or-of-select-with-zero.ll @@ -0,0 +1,247 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -passes=instcombine -S | FileCheck %s + +declare void @use.i8(i8) +declare void @use.i1(i1) +define i1 @src_tv_eq(i1 %c0, i8 %x, i8 %yy) { +; CHECK-LABEL: @src_tv_eq( +; CHECK-NEXT: [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1 +; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C0:%.*]], i8 0, i8 [[Y]] +; CHECK-NEXT: [[SELX:%.*]] = or i8 [[SEL]], [[X:%.*]] +; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[SELX]], 0 +; CHECK-NEXT: ret i1 [[R]] +; + %y = add nuw i8 %yy, 1 + %sel = select i1 %c0, i8 0, i8 %y + %selx = or i8 %sel, %x + %r = icmp eq i8 %selx, 0 + ret i1 %r +} + +define i1 @src_tv_eq_multiuse_or_fail(i1 %c0, i8 %x, i8 %yy) { +; CHECK-LABEL: @src_tv_eq_multiuse_or_fail( +; CHECK-NEXT: [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1 +; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C0:%.*]], i8 0, i8 [[Y]] +; CHECK-NEXT: [[SELX:%.*]] = or i8 [[SEL]], [[X:%.*]] +; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[SELX]], 0 +; CHECK-NEXT: call void @use.i8(i8 [[SELX]]) +; CHECK-NEXT: ret i1 [[R]] +; + %y = add nuw i8 %yy, 1 + %sel = select i1 %c0, i8 0, i8 %y + %selx = or i8 %sel, %x + %r = icmp eq i8 %selx, 0 + call void @use.i8(i8 %selx) + ret i1 %r +} + +define i1 @src_tv_eq_fail_tv_nonzero(i1 %c0, i8 %x, i8 %yy) { +; CHECK-LABEL: @src_tv_eq_fail_tv_nonzero( +; CHECK-NEXT: [[Y:%.*]] = add nsw i8 [[YY:%.*]], 1 +; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C0:%.*]], i8 1, i8 [[Y]] +; CHECK-NEXT: [[SELX:%.*]] = or i8 [[SEL]], [[X:%.*]] +; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[SELX]], 0 +; CHECK-NEXT: ret i1 [[R]] +; + %y = add nsw i8 %yy, 1 + %sel = select i1 %c0, i8 1, i8 %y + %selx = or i8 %sel, %x + %r = icmp eq i8 %selx, 0 + ret i1 %r +} + +define i1 @src_fv_ne(i1 %c0, i8 %x, i8 %yy) { +; CHECK-LABEL: @src_fv_ne( +; CHECK-NEXT: [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1 +; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C0:%.*]], i8 [[Y]], i8 0 +; CHECK-NEXT: [[SELX:%.*]] = or i8 [[SEL]], [[X:%.*]] +; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[SELX]], 0 +; CHECK-NEXT: ret i1 [[R]] +; + %y = add nuw i8 %yy, 1 + %sel = select i1 %c0, i8 %y, i8 0 + %selx = or i8 %sel, %x + %r = icmp ne i8 %selx, 0 + ret i1 %r +} + +define i1 @src_fv_ne_fail_maybe_zero(i1 %c0, i8 %x, i8 %yy) { +; CHECK-LABEL: @src_fv_ne_fail_maybe_zero( +; CHECK-NEXT: [[Y:%.*]] = add nsw i8 [[YY:%.*]], 1 +; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C0:%.*]], i8 [[Y]], i8 0 +; CHECK-NEXT: [[SELX:%.*]] = or i8 [[SEL]], [[X:%.*]] +; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[SELX]], 0 +; CHECK-NEXT: ret i1 [[R]] +; + %y = add nsw i8 %yy, 1 + %sel = select i1 %c0, i8 %y, i8 0 + %selx = or i8 %sel, %x + %r = icmp ne i8 %selx, 0 + ret i1 %r +} + +define i1 @src_tv_ne(i1 %c0, i8 %x, i8 %yy) { +; CHECK-LABEL: @src_tv_ne( +; CHECK-NEXT: [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1 +; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C0:%.*]], i8 0, i8 [[Y]] +; CHECK-NEXT: [[SELX:%.*]] = or i8 [[SEL]], [[X:%.*]] +; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[SELX]], 0 +; CHECK-NEXT: ret i1 [[R]] +; + %y = add nuw i8 %yy, 1 + %sel = select i1 %c0, i8 0, i8 %y + %selx = or i8 %sel, %x + %r = icmp ne i8 %selx, 0 + ret i1 %r +} + +define i1 @src_tv_ne_fail_cmp_nonzero(i1 %c0, i8 %x, i8 %yy) { +; CHECK-LABEL: @src_tv_ne_fail_cmp_nonzero( +; CHECK-NEXT: [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1 +; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C0:%.*]], i8 0, i8 [[Y]] +; CHECK-NEXT: [[SELX:%.*]] = or i8 [[SEL]], [[X:%.*]] +; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[SELX]], 1 +; CHECK-NEXT: ret i1 [[R]] +; + %y = add nuw i8 %yy, 1 + %sel = select i1 %c0, i8 0, i8 %y + %selx = or i8 %sel, %x + %r = icmp ne i8 %selx, 1 + ret i1 %r +} + +define i1 @src_fv_eq(i1 %c0, i8 %x, i8 %yy) { +; CHECK-LABEL: @src_fv_eq( +; CHECK-NEXT: [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1 +; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C0:%.*]], i8 [[Y]], i8 0 +; CHECK-NEXT: [[SELX:%.*]] = or i8 [[SEL]], [[X:%.*]] +; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[SELX]], 0 +; CHECK-NEXT: ret i1 [[R]] +; + %y = add nuw i8 %yy, 1 + %sel = select i1 %c0, i8 %y, i8 0 + %selx = or i8 %sel, %x + %r = icmp eq i8 %selx, 0 + ret i1 %r +} + +define i1 @src_fv_eq_fail_cant_invert(i1 %c0, i8 %x, i8 %yy) { +; CHECK-LABEL: @src_fv_eq_fail_cant_invert( +; CHECK-NEXT: [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1 +; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C0:%.*]], i8 [[Y]], i8 0 +; CHECK-NEXT: [[SELX:%.*]] = or i8 [[SEL]], [[X:%.*]] +; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[SELX]], 0 +; CHECK-NEXT: call void @use.i8(i8 [[SEL]]) +; CHECK-NEXT: ret i1 [[R]] +; + %y = add nuw i8 %yy, 1 + %sel = select i1 %c0, i8 %y, i8 0 + %selx = or i8 %sel, %x + %r = icmp eq i8 %selx, 0 + call void @use.i8(i8 %sel) + ret i1 %r +} + +define i1 @src_fv_eq_fail_cant_invert2(i1 %c1, i8 %a, i8 %b, i8 %x, i8 %yy) { +; CHECK-LABEL: @src_fv_eq_fail_cant_invert2( +; CHECK-NEXT: [[C0:%.*]] = icmp ugt i8 [[A:%.*]], [[B:%.*]] +; CHECK-NEXT: [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1 +; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C0]], i8 [[Y]], i8 0 +; CHECK-NEXT: [[CC:%.*]] = or i1 [[C0]], [[C1:%.*]] +; CHECK-NEXT: [[SEL_OTHER:%.*]] = select i1 [[CC]], i8 [[Y]], i8 [[B]] +; CHECK-NEXT: [[SELX:%.*]] = or i8 [[SEL]], [[X:%.*]] +; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[SELX]], 0 +; CHECK-NEXT: call void @use.i8(i8 [[SEL]]) +; CHECK-NEXT: call void @use.i8(i8 [[SEL_OTHER]]) +; CHECK-NEXT: ret i1 [[R]] +; + %c0 = icmp ugt i8 %a, %b + %y = add nuw i8 %yy, 1 + %sel = select i1 %c0, i8 %y, i8 0 + %cc = or i1 %c0, %c1 + %sel_other = select i1 %cc, i8 %y, i8 %b + + %selx = or i8 %sel, %x + %r = icmp eq i8 %selx, 0 + call void @use.i8(i8 %sel) + call void @use.i8(i8 %sel_other) + ret i1 %r +} + +define i1 @src_fv_eq_invert2(i1 %c1, i8 %a, i8 %b, i8 %x, i8 %yy) { +; CHECK-LABEL: @src_fv_eq_invert2( +; CHECK-NEXT: [[C0:%.*]] = icmp ugt i8 [[A:%.*]], [[B:%.*]] +; CHECK-NEXT: [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1 +; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C0]], i8 [[Y]], i8 0 +; CHECK-NEXT: [[CC:%.*]] = or i1 [[C0]], [[C1:%.*]] +; CHECK-NEXT: [[SEL_OTHER:%.*]] = select i1 [[CC]], i8 [[Y]], i8 [[B]] +; CHECK-NEXT: [[SELX:%.*]] = or i8 [[SEL]], [[X:%.*]] +; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[SELX]], 0 +; CHECK-NEXT: call void @use.i8(i8 [[SEL_OTHER]]) +; CHECK-NEXT: ret i1 [[R]] +; + %c0 = icmp ugt i8 %a, %b + %y = add nuw i8 %yy, 1 + %sel = select i1 %c0, i8 %y, i8 0 + %cc = or i1 %c0, %c1 + %sel_other = select i1 %cc, i8 %y, i8 %b + + %selx = or i8 %sel, %x + %r = icmp eq i8 %selx, 0 + call void @use.i8(i8 %sel_other) + ret i1 %r +} + +define i1 @src_fv_eq_invert3(i8 %a, i8 %b, i8 %x, i8 %yy) { +; CHECK-LABEL: @src_fv_eq_invert3( +; CHECK-NEXT: [[C0:%.*]] = icmp ugt i8 [[A:%.*]], [[B:%.*]] +; CHECK-NEXT: [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1 +; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C0]], i8 [[Y]], i8 0 +; CHECK-NEXT: [[SEL_OTHER:%.*]] = select i1 [[C0]], i8 [[Y]], i8 [[B]] +; CHECK-NEXT: [[SELX:%.*]] = or i8 [[SEL]], [[X:%.*]] +; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[SELX]], 0 +; CHECK-NEXT: call void @use.i8(i8 [[SEL_OTHER]]) +; CHECK-NEXT: call void @use.i8(i8 [[SEL]]) +; CHECK-NEXT: ret i1 [[R]] +; + %c0 = icmp ugt i8 %a, %b + %y = add nuw i8 %yy, 1 + %sel = select i1 %c0, i8 %y, i8 0 + %sel_other = select i1 %c0, i8 %y, i8 %b + + %selx = or i8 %sel, %x + %r = icmp eq i8 %selx, 0 + call void @use.i8(i8 %sel_other) + call void @use.i8(i8 %sel) + ret i1 %r +} + +define i1 @src_tv_ne_invert(i1 %c1, i8 %a, i8 %b, i8 %x, i8 %yy) { +; CHECK-LABEL: @src_tv_ne_invert( +; CHECK-NEXT: [[NOT_C0:%.*]] = icmp ugt i8 [[A:%.*]], [[B:%.*]] +; CHECK-NEXT: call void @use.i1(i1 [[NOT_C0]]) +; CHECK-NEXT: [[C0:%.*]] = xor i1 [[NOT_C0]], true +; CHECK-NEXT: [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1 +; CHECK-NEXT: [[SEL:%.*]] = select i1 [[NOT_C0]], i8 [[Y]], i8 0 +; CHECK-NEXT: [[CC:%.*]] = or i1 [[C0]], [[C1:%.*]] +; CHECK-NEXT: [[SEL_OTHER:%.*]] = select i1 [[CC]], i8 [[Y]], i8 [[B]] +; CHECK-NEXT: [[SELX:%.*]] = or i8 [[SEL]], [[X:%.*]] +; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[SELX]], 0 +; CHECK-NEXT: call void @use.i8(i8 [[SEL]]) +; CHECK-NEXT: call void @use.i8(i8 [[SEL_OTHER]]) +; CHECK-NEXT: ret i1 [[R]] +; + %not_c0 = icmp ugt i8 %a, %b + call void @use.i1(i1 %not_c0) + %c0 = xor i1 %not_c0, true + %y = add nuw i8 %yy, 1 + %sel = select i1 %c0, i8 0, i8 %y + %cc = or i1 %c0, %c1 + %sel_other = select i1 %cc, i8 %y, i8 %b + + %selx = or i8 %sel, %x + %r = icmp ne i8 %selx, 0 + call void @use.i8(i8 %sel) + call void @use.i8(i8 %sel_other) + ret i1 %r +}