diff --git a/llvm/test/Transforms/InstCombine/free-inversion.ll b/llvm/test/Transforms/InstCombine/free-inversion.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/free-inversion.ll @@ -0,0 +1,403 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -passes=instcombine -S | FileCheck %s + +declare i8 @llvm.smin.i8(i8, i8) +declare i8 @llvm.umin.i8(i8, i8) +declare i8 @llvm.smax.i8(i8, i8) +declare i8 @llvm.umax.i8(i8, i8) + +declare void @use.i8(i8) + +define i8 @xor_1(i8 %a, i1 %c, i8 %x, i8 %y) { +; CHECK-LABEL: @xor_1( +; CHECK-NEXT: [[NX:%.*]] = xor i8 [[X:%.*]], -1 +; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], 123 +; CHECK-NEXT: [[B:%.*]] = select i1 [[C:%.*]], i8 [[NX]], i8 [[YY]] +; CHECK-NEXT: [[BA:%.*]] = xor i8 [[B]], [[A:%.*]] +; CHECK-NEXT: [[NOT_BA:%.*]] = xor i8 [[BA]], -1 +; CHECK-NEXT: ret i8 [[NOT_BA]] +; + %nx = xor i8 %x, -1 + %yy = xor i8 %y, 123 + %b = select i1 %c, i8 %nx, i8 %yy + %ba = xor i8 %b, %a + %not_ba = xor i8 %ba, -1 + ret i8 %not_ba +} + +define i8 @xor_2(i8 %a, i1 %c, i8 %x, i8 %y) { +; CHECK-LABEL: @xor_2( +; CHECK-NEXT: [[NX:%.*]] = xor i8 [[X:%.*]], -1 +; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], 123 +; CHECK-NEXT: [[B:%.*]] = select i1 [[C:%.*]], i8 [[NX]], i8 [[YY]] +; CHECK-NEXT: [[AB:%.*]] = xor i8 [[B]], [[A:%.*]] +; CHECK-NEXT: [[NOT_AB:%.*]] = xor i8 [[AB]], -1 +; CHECK-NEXT: ret i8 [[NOT_AB]] +; + %nx = xor i8 %x, -1 + %yy = xor i8 %y, 123 + %b = select i1 %c, i8 %nx, i8 %yy + %ab = xor i8 %a, %b + %not_ab = xor i8 %ab, -1 + ret i8 %not_ab +} + +define i8 @xor_fail(i8 %a, i1 %c, i8 %x, i8 %y) { +; CHECK-LABEL: @xor_fail( +; CHECK-NEXT: [[NX:%.*]] = xor i8 [[X:%.*]], -1 +; CHECK-NEXT: [[B:%.*]] = select i1 [[C:%.*]], i8 [[NX]], i8 [[Y:%.*]] +; CHECK-NEXT: [[AB:%.*]] = xor i8 [[B]], [[A:%.*]] +; CHECK-NEXT: [[NOT_AB:%.*]] = xor i8 [[AB]], -1 +; CHECK-NEXT: ret i8 [[NOT_AB]] +; + %nx = xor i8 %x, -1 + %b = select i1 %c, i8 %nx, i8 %y + %ab = xor i8 %a, %b + %not_ab = xor i8 %ab, -1 + ret i8 %not_ab +} + +define i8 @add_1(i8 %a, i1 %c, i8 %x, i8 %y) { +; CHECK-LABEL: @add_1( +; CHECK-NEXT: [[NX:%.*]] = xor i8 [[X:%.*]], -1 +; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], 123 +; CHECK-NEXT: [[B:%.*]] = select i1 [[C:%.*]], i8 [[NX]], i8 [[YY]] +; CHECK-NEXT: [[BA:%.*]] = add i8 [[B]], [[A:%.*]] +; CHECK-NEXT: [[NOT_BA:%.*]] = xor i8 [[BA]], -1 +; CHECK-NEXT: ret i8 [[NOT_BA]] +; + %nx = xor i8 %x, -1 + %yy = xor i8 %y, 123 + %b = select i1 %c, i8 %nx, i8 %yy + %ba = add i8 %b, %a + %not_ba = xor i8 %ba, -1 + ret i8 %not_ba +} + +define i8 @add_2(i8 %a, i1 %c, i8 %x, i8 %y) { +; CHECK-LABEL: @add_2( +; CHECK-NEXT: [[NX:%.*]] = xor i8 [[X:%.*]], -1 +; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], 123 +; CHECK-NEXT: [[B:%.*]] = select i1 [[C:%.*]], i8 [[NX]], i8 [[YY]] +; CHECK-NEXT: [[AB:%.*]] = add i8 [[B]], [[A:%.*]] +; CHECK-NEXT: [[NOT_AB:%.*]] = xor i8 [[AB]], -1 +; CHECK-NEXT: ret i8 [[NOT_AB]] +; + %nx = xor i8 %x, -1 + %yy = xor i8 %y, 123 + %b = select i1 %c, i8 %nx, i8 %yy + %ab = add i8 %a, %b + %not_ab = xor i8 %ab, -1 + ret i8 %not_ab +} + +define i8 @add_fail(i8 %a, i1 %c, i8 %x, i8 %y) { +; CHECK-LABEL: @add_fail( +; CHECK-NEXT: [[NX:%.*]] = xor i8 [[X:%.*]], [[A:%.*]] +; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], 123 +; CHECK-NEXT: [[B:%.*]] = select i1 [[C:%.*]], i8 [[NX]], i8 [[YY]] +; CHECK-NEXT: [[AB:%.*]] = add i8 [[B]], [[A]] +; CHECK-NEXT: [[NOT_AB:%.*]] = xor i8 [[AB]], -1 +; CHECK-NEXT: ret i8 [[NOT_AB]] +; + %nx = xor i8 %x, %a + %yy = xor i8 %y, 123 + %b = select i1 %c, i8 %nx, i8 %yy + %ab = add i8 %a, %b + %not_ab = xor i8 %ab, -1 + ret i8 %not_ab +} + +define i8 @sub_1(i8 %a, i1 %c, i8 %x, i8 %y) { +; CHECK-LABEL: @sub_1( +; CHECK-NEXT: [[NX:%.*]] = xor i8 [[X:%.*]], -1 +; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], 123 +; CHECK-NEXT: [[B:%.*]] = select i1 [[C:%.*]], i8 [[NX]], i8 [[YY]] +; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[B]], -1 +; CHECK-NEXT: [[NOT_BA:%.*]] = add i8 [[TMP1]], [[A:%.*]] +; CHECK-NEXT: ret i8 [[NOT_BA]] +; + %nx = xor i8 %x, -1 + %yy = xor i8 %y, 123 + %b = select i1 %c, i8 %nx, i8 %yy + %ba = sub i8 %b, %a + %not_ba = xor i8 %ba, -1 + ret i8 %not_ba +} + +define i8 @sub_2(i8 %a, i1 %c, i8 %x, i8 %y) { +; CHECK-LABEL: @sub_2( +; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[Y:%.*]], -124 +; CHECK-NEXT: [[B_NEG_V:%.*]] = select i1 [[C:%.*]], i8 [[X:%.*]], i8 [[TMP1]] +; CHECK-NEXT: [[B_NEG:%.*]] = add i8 [[B_NEG_V]], 1 +; CHECK-NEXT: [[AB:%.*]] = add i8 [[B_NEG]], [[A:%.*]] +; CHECK-NEXT: [[NOT_AB:%.*]] = xor i8 [[AB]], -1 +; CHECK-NEXT: ret i8 [[NOT_AB]] +; + %nx = xor i8 %x, -1 + %yy = xor i8 %y, 123 + %b = select i1 %c, i8 %nx, i8 %yy + %ab = sub i8 %a, %b + %not_ab = xor i8 %ab, -1 + ret i8 %not_ab +} + +define i8 @sub_fail(i8 %a, i1 %c, i8 %x, i8 %y) { +; CHECK-LABEL: @sub_fail( +; CHECK-NEXT: [[NX:%.*]] = xor i8 [[X:%.*]], -1 +; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], 123 +; CHECK-NEXT: call void @use.i8(i8 [[NX]]) +; CHECK-NEXT: [[B:%.*]] = select i1 [[C:%.*]], i8 [[NX]], i8 [[YY]] +; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[B]], -1 +; CHECK-NEXT: [[NOT_BA:%.*]] = add i8 [[TMP1]], [[A:%.*]] +; CHECK-NEXT: ret i8 [[NOT_BA]] +; + %nx = xor i8 %x, -1 + %yy = xor i8 %y, 123 + call void @use.i8(i8 %nx) + %b = select i1 %c, i8 %nx, i8 %yy + %ba = sub i8 %b, %a + %not_ba = xor i8 %ba, -1 + ret i8 %not_ba +} + +define i8 @ashr_1(i8 %a, i1 %c, i8 %x, i8 %y) { +; CHECK-LABEL: @ashr_1( +; CHECK-NEXT: [[NX:%.*]] = xor i8 [[X:%.*]], -1 +; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], 123 +; CHECK-NEXT: [[B:%.*]] = select i1 [[C:%.*]], i8 [[NX]], i8 [[YY]] +; CHECK-NEXT: [[BA:%.*]] = ashr i8 [[B]], [[A:%.*]] +; CHECK-NEXT: [[NOT_BA:%.*]] = xor i8 [[BA]], -1 +; CHECK-NEXT: ret i8 [[NOT_BA]] +; + %nx = xor i8 %x, -1 + %yy = xor i8 %y, 123 + %b = select i1 %c, i8 %nx, i8 %yy + %ba = ashr i8 %b, %a + %not_ba = xor i8 %ba, -1 + ret i8 %not_ba +} + +define i8 @ashr_2_fail(i8 %a, i1 %c, i8 %x, i8 %y) { +; CHECK-LABEL: @ashr_2_fail( +; CHECK-NEXT: [[NX:%.*]] = xor i8 [[X:%.*]], -1 +; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], 123 +; CHECK-NEXT: [[B:%.*]] = select i1 [[C:%.*]], i8 [[NX]], i8 [[YY]] +; CHECK-NEXT: [[AB:%.*]] = ashr i8 [[A:%.*]], [[B]] +; CHECK-NEXT: [[NOT_AB:%.*]] = xor i8 [[AB]], -1 +; CHECK-NEXT: ret i8 [[NOT_AB]] +; + %nx = xor i8 %x, -1 + %yy = xor i8 %y, 123 + %b = select i1 %c, i8 %nx, i8 %yy + %ab = ashr i8 %a, %b + %not_ab = xor i8 %ab, -1 + ret i8 %not_ab +} + +define i8 @select_1(i1 %cc, i8 %na, i8 %aa, i1 %c, i8 %x, i8 %y) { +; CHECK-LABEL: @select_1( +; CHECK-NEXT: [[NX:%.*]] = xor i8 [[X:%.*]], -1 +; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], 123 +; CHECK-NEXT: [[B:%.*]] = select i1 [[C:%.*]], i8 [[NX]], i8 [[YY]] +; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[NA:%.*]], [[AA:%.*]] +; CHECK-NEXT: [[A:%.*]] = xor i8 [[TMP1]], 45 +; CHECK-NEXT: [[AB:%.*]] = select i1 [[CC:%.*]], i8 [[A]], i8 [[B]] +; CHECK-NEXT: [[NOT_AB:%.*]] = xor i8 [[AB]], -1 +; CHECK-NEXT: ret i8 [[NOT_AB]] +; + %nx = xor i8 %x, -1 + %yy = xor i8 %y, 123 + %b = select i1 %c, i8 %nx, i8 %yy + %nna = xor i8 %na, 45 + %a = xor i8 %aa, %nna + %ab = select i1 %cc, i8 %a, i8 %b + %not_ab = xor i8 %ab, -1 + ret i8 %not_ab +} + +define i8 @select_2(i1 %cc, i8 %na, i1 %c, i8 %x, i8 %y) { +; CHECK-LABEL: @select_2( +; CHECK-NEXT: [[NX:%.*]] = xor i8 [[X:%.*]], -1 +; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], 123 +; CHECK-NEXT: [[B:%.*]] = select i1 [[C:%.*]], i8 [[NX]], i8 [[YY]] +; CHECK-NEXT: [[A:%.*]] = xor i8 [[NA:%.*]], 45 +; CHECK-NEXT: [[BA:%.*]] = select i1 [[CC:%.*]], i8 [[B]], i8 [[A]] +; CHECK-NEXT: [[NOT_BA:%.*]] = xor i8 [[BA]], -1 +; CHECK-NEXT: ret i8 [[NOT_BA]] +; + %nx = xor i8 %x, -1 + %yy = xor i8 %y, 123 + %b = select i1 %c, i8 %nx, i8 %yy + %a = xor i8 %na, 45 + %ba = select i1 %cc, i8 %b, i8 %a + %not_ba = xor i8 %ba, -1 + ret i8 %not_ba +} + +define i1 @select_logic_or_fail(i1 %cc, i1 %c, i1 %x, i8 %y) { +; CHECK-LABEL: @select_logic_or_fail( +; CHECK-NEXT: [[NX:%.*]] = xor i1 [[X:%.*]], true +; CHECK-NEXT: [[YY:%.*]] = icmp eq i8 [[Y:%.*]], 123 +; CHECK-NEXT: [[B:%.*]] = select i1 [[C:%.*]], i1 [[NX]], i1 [[YY]] +; CHECK-NEXT: [[AB:%.*]] = select i1 [[CC:%.*]], i1 [[B]], i1 false +; CHECK-NEXT: [[NOT_AB:%.*]] = xor i1 [[AB]], true +; CHECK-NEXT: ret i1 [[NOT_AB]] +; + %nx = xor i1 %x, -1 + %yy = icmp eq i8 %y, 123 + %b = select i1 %c, i1 %nx, i1 %yy + %ab = select i1 %cc, i1 %b, i1 false + %not_ab = xor i1 %ab, -1 + ret i1 %not_ab +} + +define i1 @select_logic_and_fail(i1 %cc, i1 %c, i1 %x, i8 %y) { +; CHECK-LABEL: @select_logic_and_fail( +; CHECK-NEXT: [[NX:%.*]] = xor i1 [[X:%.*]], true +; CHECK-NEXT: [[YY:%.*]] = icmp eq i8 [[Y:%.*]], 123 +; CHECK-NEXT: [[B:%.*]] = select i1 [[C:%.*]], i1 [[NX]], i1 [[YY]] +; CHECK-NEXT: [[AB:%.*]] = select i1 [[CC:%.*]], i1 true, i1 [[B]] +; CHECK-NEXT: [[NOT_AB:%.*]] = xor i1 [[AB]], true +; CHECK-NEXT: ret i1 [[NOT_AB]] +; + %nx = xor i1 %x, -1 + %yy = icmp eq i8 %y, 123 + %b = select i1 %c, i1 %nx, i1 %yy + %ab = select i1 %cc, i1 true, i1 %b + %not_ab = xor i1 %ab, -1 + ret i1 %not_ab +} + +define i8 @smin_1(i8 %aa, i8 %na, i1 %c, i8 %x, i8 %y) { +; CHECK-LABEL: @smin_1( +; CHECK-NEXT: [[NX:%.*]] = xor i8 [[X:%.*]], -1 +; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], 123 +; CHECK-NEXT: [[B:%.*]] = select i1 [[C:%.*]], i8 [[NX]], i8 [[YY]] +; CHECK-NEXT: [[NNA:%.*]] = xor i8 [[NA:%.*]], -1 +; CHECK-NEXT: [[A:%.*]] = add i8 [[NNA]], [[AA:%.*]] +; CHECK-NEXT: [[AB:%.*]] = call i8 @llvm.smin.i8(i8 [[A]], i8 [[B]]) +; CHECK-NEXT: [[NOT_AB:%.*]] = xor i8 [[AB]], -1 +; CHECK-NEXT: ret i8 [[NOT_AB]] +; + %nx = xor i8 %x, -1 + %yy = xor i8 %y, 123 + %b = select i1 %c, i8 %nx, i8 %yy + %nna = xor i8 %na, -1 + %a = add i8 %aa, %nna + %ab = call i8 @llvm.smin.i8(i8 %a, i8 %b) + %not_ab = xor i8 %ab, -1 + ret i8 %not_ab +} + +define i8 @smin_1_fail(i8 %a, i1 %c, i8 %x, i8 %y) { +; CHECK-LABEL: @smin_1_fail( +; CHECK-NEXT: [[NX:%.*]] = xor i8 [[X:%.*]], -1 +; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], 123 +; CHECK-NEXT: [[B:%.*]] = select i1 [[C:%.*]], i8 [[NX]], i8 [[YY]] +; CHECK-NEXT: [[AB:%.*]] = call i8 @llvm.smin.i8(i8 [[A:%.*]], i8 [[B]]) +; CHECK-NEXT: [[NOT_AB:%.*]] = xor i8 [[AB]], -1 +; CHECK-NEXT: ret i8 [[NOT_AB]] +; + %nx = xor i8 %x, -1 + %yy = xor i8 %y, 123 + %b = select i1 %c, i8 %nx, i8 %yy + %ab = call i8 @llvm.smin.i8(i8 %a, i8 %b) + %not_ab = xor i8 %ab, -1 + ret i8 %not_ab +} + +define i8 @umin_1_fail(i1 %c, i8 %x, i8 %y) { +; CHECK-LABEL: @umin_1_fail( +; CHECK-NEXT: [[NX:%.*]] = xor i8 [[X:%.*]], -1 +; CHECK-NEXT: [[B:%.*]] = select i1 [[C:%.*]], i8 [[NX]], i8 [[Y:%.*]] +; CHECK-NEXT: [[BA:%.*]] = call i8 @llvm.umin.i8(i8 [[B]], i8 85) +; CHECK-NEXT: [[NOT_BA:%.*]] = xor i8 [[BA]], -1 +; CHECK-NEXT: ret i8 [[NOT_BA]] +; + %nx = xor i8 %x, -1 + %b = select i1 %c, i8 %nx, i8 %y + %ba = call i8 @llvm.umin.i8(i8 %b, i8 85) + %not_ba = xor i8 %ba, -1 + ret i8 %not_ba +} + +define i8 @smax_1(i8 %aa, i8 %na, i1 %c, i8 %x, i8 %y) { +; CHECK-LABEL: @smax_1( +; CHECK-NEXT: [[NX:%.*]] = xor i8 [[X:%.*]], -1 +; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], 123 +; CHECK-NEXT: [[B:%.*]] = select i1 [[C:%.*]], i8 [[NX]], i8 [[YY]] +; CHECK-NEXT: [[NNA:%.*]] = xor i8 [[NA:%.*]], -1 +; CHECK-NEXT: [[A:%.*]] = sub i8 [[NNA]], [[AA:%.*]] +; CHECK-NEXT: [[AB:%.*]] = call i8 @llvm.smax.i8(i8 [[A]], i8 [[B]]) +; CHECK-NEXT: [[NOT_AB:%.*]] = xor i8 [[AB]], -1 +; CHECK-NEXT: ret i8 [[NOT_AB]] +; + %nx = xor i8 %x, -1 + %yy = xor i8 %y, 123 + %b = select i1 %c, i8 %nx, i8 %yy + %nna = xor i8 %na, -1 + %a = sub i8 %nna, %aa + %ab = call i8 @llvm.smax.i8(i8 %a, i8 %b) + %not_ab = xor i8 %ab, -1 + ret i8 %not_ab +} + +define i8 @smax_1_fail(i8 %aa, i8 %na, i1 %c, i8 %x, i8 %y) { +; CHECK-LABEL: @smax_1_fail( +; CHECK-NEXT: [[NX:%.*]] = xor i8 [[X:%.*]], -1 +; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], 123 +; CHECK-NEXT: call void @use.i8(i8 [[YY]]) +; CHECK-NEXT: [[B:%.*]] = select i1 [[C:%.*]], i8 [[NX]], i8 [[YY]] +; CHECK-NEXT: [[NNA:%.*]] = xor i8 [[NA:%.*]], -1 +; CHECK-NEXT: [[A:%.*]] = sub i8 [[NNA]], [[AA:%.*]] +; CHECK-NEXT: [[AB:%.*]] = call i8 @llvm.smax.i8(i8 [[A]], i8 [[B]]) +; CHECK-NEXT: [[NOT_AB:%.*]] = xor i8 [[AB]], -1 +; CHECK-NEXT: ret i8 [[NOT_AB]] +; + %nx = xor i8 %x, -1 + %yy = xor i8 %y, 123 + call void @use.i8(i8 %yy) + %b = select i1 %c, i8 %nx, i8 %yy + %nna = xor i8 %na, -1 + %a = sub i8 %nna, %aa + %ab = call i8 @llvm.smax.i8(i8 %a, i8 %b) + %not_ab = xor i8 %ab, -1 + ret i8 %not_ab +} + +define i8 @umax_1(i8 %na, i1 %c, i8 %x, i8 %y) { +; CHECK-LABEL: @umax_1( +; CHECK-NEXT: [[NX:%.*]] = xor i8 [[X:%.*]], -1 +; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], 123 +; CHECK-NEXT: [[B:%.*]] = select i1 [[C:%.*]], i8 [[NX]], i8 [[YY]] +; CHECK-NEXT: [[BA:%.*]] = call i8 @llvm.umax.i8(i8 [[B]], i8 85) +; CHECK-NEXT: [[NOT_BA:%.*]] = xor i8 [[BA]], -1 +; CHECK-NEXT: ret i8 [[NOT_BA]] +; + %nx = xor i8 %x, -1 + %yy = xor i8 %y, 123 + %b = select i1 %c, i8 %nx, i8 %yy + %ba = call i8 @llvm.umax.i8(i8 %b, i8 85) + %not_ba = xor i8 %ba, -1 + ret i8 %not_ba +} + +define i8 @umax_1_fail(i8 %na, i1 %c, i8 %x, i8 %y) { +; CHECK-LABEL: @umax_1_fail( +; CHECK-NEXT: [[NX:%.*]] = xor i8 [[X:%.*]], -1 +; CHECK-NEXT: [[YY:%.*]] = xor i8 [[Y:%.*]], 123 +; CHECK-NEXT: [[B:%.*]] = select i1 [[C:%.*]], i8 [[NX]], i8 [[YY]] +; CHECK-NEXT: call void @use.i8(i8 [[B]]) +; CHECK-NEXT: [[BA:%.*]] = call i8 @llvm.umax.i8(i8 [[B]], i8 85) +; CHECK-NEXT: [[NOT_BA:%.*]] = xor i8 [[BA]], -1 +; CHECK-NEXT: ret i8 [[NOT_BA]] +; + %nx = xor i8 %x, -1 + %yy = xor i8 %y, 123 + %b = select i1 %c, i8 %nx, i8 %yy + call void @use.i8(i8 %b) + %ba = call i8 @llvm.umax.i8(i8 %b, i8 85) + %not_ba = xor i8 %ba, -1 + ret i8 %not_ba +}