From c066a92657a78f13b5e490e1b51c11d740671de0 Mon Sep 17 00:00:00 2001 From: David Green Date: Tue, 2 Oct 2018 09:06:49 +0000 Subject: [PATCH] [InstCombine] Tests for ~A - Min/Max(~A, O) -> Max/Min(A, ~O) - A. NFC llvm-svn: 343561 --- llvm/test/Transforms/InstCombine/max-of-nots.ll | 35 --- llvm/test/Transforms/InstCombine/sub-minmax.ll | 359 ++++++++++++++++++++++++ 2 files changed, 359 insertions(+), 35 deletions(-) create mode 100644 llvm/test/Transforms/InstCombine/sub-minmax.ll diff --git a/llvm/test/Transforms/InstCombine/max-of-nots.ll b/llvm/test/Transforms/InstCombine/max-of-nots.ll index 3e38718..b8643f5 100644 --- a/llvm/test/Transforms/InstCombine/max-of-nots.ll +++ b/llvm/test/Transforms/InstCombine/max-of-nots.ll @@ -161,41 +161,6 @@ define i8 @umin3_not_all_ops_extra_uses(i8 %x, i8 %y, i8 %z) { ret i8 %minxyz } -define void @umin3_not_all_ops_extra_uses_invert_subs(i8 %x, i8 %y, i8 %z) { -; CHECK-LABEL: @umin3_not_all_ops_extra_uses_invert_subs( -; CHECK-NEXT: [[XN:%.*]] = xor i8 [[X:%.*]], -1 -; CHECK-NEXT: [[YN:%.*]] = xor i8 [[Y:%.*]], -1 -; CHECK-NEXT: [[ZN:%.*]] = xor i8 [[Z:%.*]], -1 -; CHECK-NEXT: [[CMPXZ:%.*]] = icmp ult i8 [[XN]], [[ZN]] -; CHECK-NEXT: [[MINXZ:%.*]] = select i1 [[CMPXZ]], i8 [[XN]], i8 [[ZN]] -; CHECK-NEXT: [[CMPXYZ:%.*]] = icmp ult i8 [[MINXZ]], [[YN]] -; CHECK-NEXT: [[MINXYZ:%.*]] = select i1 [[CMPXYZ]], i8 [[MINXZ]], i8 [[YN]] -; CHECK-NEXT: [[XMIN:%.*]] = sub i8 [[XN]], [[MINXYZ]] -; CHECK-NEXT: [[YMIN:%.*]] = sub i8 [[YN]], [[MINXYZ]] -; CHECK-NEXT: [[ZMIN:%.*]] = sub i8 [[ZN]], [[MINXYZ]] -; CHECK-NEXT: call void @use8(i8 [[MINXYZ]]) -; CHECK-NEXT: call void @use8(i8 [[XMIN]]) -; CHECK-NEXT: call void @use8(i8 [[YMIN]]) -; CHECK-NEXT: call void @use8(i8 [[ZMIN]]) -; CHECK-NEXT: ret void -; - %xn = xor i8 %x, -1 - %yn = xor i8 %y, -1 - %zn = xor i8 %z, -1 - %cmpxz = icmp ult i8 %xn, %zn - %minxz = select i1 %cmpxz, i8 %xn, i8 %zn - %cmpxyz = icmp ult i8 %minxz, %yn - %minxyz = select i1 %cmpxyz, i8 %minxz, i8 %yn - %xmin = sub i8 %xn, %minxyz - %ymin = sub i8 %yn, %minxyz - %zmin = sub i8 %zn, %minxyz - call void @use8(i8 %minxyz) - call void @use8(i8 %xmin) - call void @use8(i8 %ymin) - call void @use8(i8 %zmin) - ret void -} - define i32 @compute_min_3(i32 %x, i32 %y, i32 %z) { ; CHECK-LABEL: @compute_min_3( ; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[Y:%.*]], [[X:%.*]] diff --git a/llvm/test/Transforms/InstCombine/sub-minmax.ll b/llvm/test/Transforms/InstCombine/sub-minmax.ll new file mode 100644 index 0000000..43a4cf1 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/sub-minmax.ll @@ -0,0 +1,359 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -instcombine -S | FileCheck %s + +define i32 @max_na_b_minux_na(i32 %A, i32 %B) { +; CHECK-LABEL: @max_na_b_minux_na( +; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[A:%.*]], -1 +; CHECK-NEXT: [[L0:%.*]] = icmp ult i32 [[NOT]], [[B:%.*]] +; CHECK-NEXT: [[L1:%.*]] = select i1 [[L0]], i32 [[NOT]], i32 [[B]] +; CHECK-NEXT: [[X:%.*]] = sub i32 [[L1]], [[NOT]] +; CHECK-NEXT: ret i32 [[X]] +; + %not = xor i32 %A, -1 + %l0 = icmp ult i32 %not, %B + %l1 = select i1 %l0, i32 %not, i32 %B + %x = sub i32 %l1, %not + ret i32 %x +} + +define i32 @na_minus_max_na_b(i32 %A, i32 %B) { +; CHECK-LABEL: @na_minus_max_na_b( +; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[A:%.*]], -1 +; CHECK-NEXT: [[L0:%.*]] = icmp ult i32 [[NOT]], [[B:%.*]] +; CHECK-NEXT: [[L1:%.*]] = select i1 [[L0]], i32 [[NOT]], i32 [[B]] +; CHECK-NEXT: [[X:%.*]] = sub i32 [[NOT]], [[L1]] +; CHECK-NEXT: ret i32 [[X]] +; + %not = xor i32 %A, -1 + %l0 = icmp ult i32 %not, %B + %l1 = select i1 %l0, i32 %not, i32 %B + %x = sub i32 %not, %l1 + ret i32 %x +} + +define i32 @max_b_na_minus_na(i32 %A, i32 %B) { +; CHECK-LABEL: @max_b_na_minus_na( +; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[A:%.*]], -1 +; CHECK-NEXT: [[L0:%.*]] = icmp ugt i32 [[NOT]], [[B:%.*]] +; CHECK-NEXT: [[L1:%.*]] = select i1 [[L0]], i32 [[B]], i32 [[NOT]] +; CHECK-NEXT: [[X:%.*]] = sub i32 [[L1]], [[NOT]] +; CHECK-NEXT: ret i32 [[X]] +; + %not = xor i32 %A, -1 + %l0 = icmp ugt i32 %not, %B + %l1 = select i1 %l0, i32 %B, i32 %not + %x = sub i32 %l1, %not + ret i32 %x +} + +define i32 @na_minus_max_b_na(i32 %A, i32 %B) { +; CHECK-LABEL: @na_minus_max_b_na( +; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[A:%.*]], -1 +; CHECK-NEXT: [[L0:%.*]] = icmp ugt i32 [[NOT]], [[B:%.*]] +; CHECK-NEXT: [[L1:%.*]] = select i1 [[L0]], i32 [[B]], i32 [[NOT]] +; CHECK-NEXT: [[X:%.*]] = sub i32 [[NOT]], [[L1]] +; CHECK-NEXT: ret i32 [[X]] +; + %not = xor i32 %A, -1 + %l0 = icmp ugt i32 %not, %B + %l1 = select i1 %l0, i32 %B, i32 %not + %x = sub i32 %not, %l1 + ret i32 %x +} + + +define i32 @max_na_bi_minux_na(i32 %A, i32 %Bi) { +; CHECK-LABEL: @max_na_bi_minux_na( +; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[A:%.*]], [[BI:%.*]] +; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[BI]], i32 [[A]] +; CHECK-NEXT: [[X:%.*]] = sub i32 [[A]], [[TMP2]] +; CHECK-NEXT: ret i32 [[X]] +; + %B = xor i32 %Bi, -1 + %not = xor i32 %A, -1 + %l0 = icmp ult i32 %not, %B + %l1 = select i1 %l0, i32 %not, i32 %B + %x = sub i32 %l1, %not + ret i32 %x +} + +define i32 @na_minus_max_na_bi(i32 %A, i32 %Bi) { +; CHECK-LABEL: @na_minus_max_na_bi( +; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[A:%.*]], [[BI:%.*]] +; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[BI]], i32 [[A]] +; CHECK-NEXT: [[X:%.*]] = sub i32 [[TMP2]], [[A]] +; CHECK-NEXT: ret i32 [[X]] +; + %B = xor i32 %Bi, -1 + %not = xor i32 %A, -1 + %l0 = icmp ult i32 %not, %B + %l1 = select i1 %l0, i32 %not, i32 %B + %x = sub i32 %not, %l1 + ret i32 %x +} + +define i32 @max_bi_na_minus_na(i32 %A, i32 %Bi) { +; CHECK-LABEL: @max_bi_na_minus_na( +; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[A:%.*]], [[BI:%.*]] +; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[BI]], i32 [[A]] +; CHECK-NEXT: [[X:%.*]] = sub i32 [[A]], [[TMP2]] +; CHECK-NEXT: ret i32 [[X]] +; + %B = xor i32 %Bi, -1 + %not = xor i32 %A, -1 + %l0 = icmp ugt i32 %not, %B + %l1 = select i1 %l0, i32 %B, i32 %not + %x = sub i32 %l1, %not + ret i32 %x +} + +define i32 @na_minus_max_bi_na(i32 %A, i32 %Bi) { +; CHECK-LABEL: @na_minus_max_bi_na( +; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[A:%.*]], [[BI:%.*]] +; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[BI]], i32 [[A]] +; CHECK-NEXT: [[X:%.*]] = sub i32 [[TMP2]], [[A]] +; CHECK-NEXT: ret i32 [[X]] +; + %B = xor i32 %Bi, -1 + %not = xor i32 %A, -1 + %l0 = icmp ugt i32 %not, %B + %l1 = select i1 %l0, i32 %B, i32 %not + %x = sub i32 %not, %l1 + ret i32 %x +} + + +define i32 @max_na_bi_minux_na_use(i32 %A, i32 %Bi) { +; CHECK-LABEL: @max_na_bi_minux_na_use( +; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[A:%.*]], -1 +; CHECK-NEXT: [[L0:%.*]] = icmp ult i32 [[NOT]], 31 +; CHECK-NEXT: [[L1:%.*]] = select i1 [[L0]], i32 [[NOT]], i32 31 +; CHECK-NEXT: [[X:%.*]] = sub i32 [[L1]], [[NOT]] +; CHECK-NEXT: call void @use32(i32 [[L1]]) +; CHECK-NEXT: ret i32 [[X]] +; + %not = xor i32 %A, -1 + %l0 = icmp ult i32 %not, 31 + %l1 = select i1 %l0, i32 %not, i32 31 + %x = sub i32 %l1, %not + call void @use32(i32 %l1) + ret i32 %x +} + +define i32 @na_minus_max_na_bi_use(i32 %A, i32 %Bi) { +; CHECK-LABEL: @na_minus_max_na_bi_use( +; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[A:%.*]], -1 +; CHECK-NEXT: [[L0:%.*]] = icmp ult i32 [[NOT]], 31 +; CHECK-NEXT: [[L1:%.*]] = select i1 [[L0]], i32 [[NOT]], i32 31 +; CHECK-NEXT: [[X:%.*]] = sub i32 [[NOT]], [[L1]] +; CHECK-NEXT: call void @use32(i32 [[L1]]) +; CHECK-NEXT: ret i32 [[X]] +; + %not = xor i32 %A, -1 + %l0 = icmp ult i32 %not, 31 + %l1 = select i1 %l0, i32 %not, i32 31 + %x = sub i32 %not, %l1 + call void @use32(i32 %l1) + ret i32 %x +} + +define i32 @max_bi_na_minus_na_use(i32 %A, i32 %Bi) { +; CHECK-LABEL: @max_bi_na_minus_na_use( +; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[A:%.*]], [[BI:%.*]] +; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[BI]], i32 [[A]] +; CHECK-NEXT: [[L1:%.*]] = xor i32 [[TMP2]], -1 +; CHECK-NEXT: [[X:%.*]] = sub i32 [[A]], [[TMP2]] +; CHECK-NEXT: call void @use32(i32 [[L1]]) +; CHECK-NEXT: ret i32 [[X]] +; + %not = xor i32 %A, -1 + %B = xor i32 %Bi, -1 + %l0 = icmp ult i32 %B, %not + %l1 = select i1 %l0, i32 %B, i32 %not + %x = sub i32 %l1, %not + call void @use32(i32 %l1) + ret i32 %x +} + +define i32 @na_minus_max_bi_na_use(i32 %A, i32 %Bi) { +; CHECK-LABEL: @na_minus_max_bi_na_use( +; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[A:%.*]], [[BI:%.*]] +; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[BI]], i32 [[A]] +; CHECK-NEXT: [[L1:%.*]] = xor i32 [[TMP2]], -1 +; CHECK-NEXT: [[X:%.*]] = sub i32 [[TMP2]], [[A]] +; CHECK-NEXT: call void @use32(i32 [[L1]]) +; CHECK-NEXT: ret i32 [[X]] +; + %not = xor i32 %A, -1 + %B = xor i32 %Bi, -1 + %l0 = icmp ult i32 %B, %not + %l1 = select i1 %l0, i32 %B, i32 %not + %x = sub i32 %not, %l1 + call void @use32(i32 %l1) + ret i32 %x +} + + +define i32 @max_na_bi_minux_na_use2(i32 %A, i32 %Bi) { +; CHECK-LABEL: @max_na_bi_minux_na_use2( +; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[A:%.*]], -1 +; CHECK-NEXT: [[L0:%.*]] = icmp ult i32 [[NOT]], 31 +; CHECK-NEXT: [[L1:%.*]] = select i1 [[L0]], i32 [[NOT]], i32 31 +; CHECK-NEXT: [[X:%.*]] = sub i32 [[L1]], [[NOT]] +; CHECK-NEXT: call void @use32(i32 [[L1]]) +; CHECK-NEXT: call void @use32(i32 [[NOT]]) +; CHECK-NEXT: ret i32 [[X]] +; + %not = xor i32 %A, -1 + %l0 = icmp ult i32 %not, 31 + %l1 = select i1 %l0, i32 %not, i32 31 + %x = sub i32 %l1, %not + call void @use32(i32 %l1) + call void @use32(i32 %not) + ret i32 %x +} + +define i32 @na_minus_max_na_bi_use2(i32 %A, i32 %Bi) { +; CHECK-LABEL: @na_minus_max_na_bi_use2( +; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[A:%.*]], -1 +; CHECK-NEXT: [[L0:%.*]] = icmp ult i32 [[NOT]], 31 +; CHECK-NEXT: [[L1:%.*]] = select i1 [[L0]], i32 [[NOT]], i32 31 +; CHECK-NEXT: [[X:%.*]] = sub i32 [[NOT]], [[L1]] +; CHECK-NEXT: call void @use32(i32 [[L1]]) +; CHECK-NEXT: call void @use32(i32 [[NOT]]) +; CHECK-NEXT: ret i32 [[X]] +; + %not = xor i32 %A, -1 + %l0 = icmp ult i32 %not, 31 + %l1 = select i1 %l0, i32 %not, i32 31 + %x = sub i32 %not, %l1 + call void @use32(i32 %l1) + call void @use32(i32 %not) + ret i32 %x +} + +define i32 @max_bi_na_minus_na_use2(i32 %A, i32 %Bi) { +; CHECK-LABEL: @max_bi_na_minus_na_use2( +; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[A:%.*]], -1 +; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[A]], [[BI:%.*]] +; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[BI]], i32 [[A]] +; CHECK-NEXT: [[L1:%.*]] = xor i32 [[TMP2]], -1 +; CHECK-NEXT: [[X:%.*]] = sub i32 [[A]], [[TMP2]] +; CHECK-NEXT: call void @use32(i32 [[L1]]) +; CHECK-NEXT: call void @use32(i32 [[NOT]]) +; CHECK-NEXT: ret i32 [[X]] +; + %not = xor i32 %A, -1 + %B = xor i32 %Bi, -1 + %l0 = icmp ult i32 %B, %not + %l1 = select i1 %l0, i32 %B, i32 %not + %x = sub i32 %l1, %not + call void @use32(i32 %l1) + call void @use32(i32 %not) + ret i32 %x +} + +define i32 @na_minus_max_bi_na_use2(i32 %A, i32 %Bi) { +; CHECK-LABEL: @na_minus_max_bi_na_use2( +; CHECK-NEXT: [[NOT:%.*]] = xor i32 [[A:%.*]], -1 +; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[A]], [[BI:%.*]] +; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[BI]], i32 [[A]] +; CHECK-NEXT: [[L1:%.*]] = xor i32 [[TMP2]], -1 +; CHECK-NEXT: [[X:%.*]] = sub i32 [[TMP2]], [[A]] +; CHECK-NEXT: call void @use32(i32 [[L1]]) +; CHECK-NEXT: call void @use32(i32 [[NOT]]) +; CHECK-NEXT: ret i32 [[X]] +; + %not = xor i32 %A, -1 + %B = xor i32 %Bi, -1 + %l0 = icmp ult i32 %B, %not + %l1 = select i1 %l0, i32 %B, i32 %not + %x = sub i32 %not, %l1 + call void @use32(i32 %l1) + call void @use32(i32 %not) + ret i32 %x +} + +define i8 @umin_not_sub(i8 %x, i8 %y) { +; CHECK-LABEL: @umin_not_sub( +; CHECK-NEXT: [[NX:%.*]] = xor i8 [[X:%.*]], -1 +; CHECK-NEXT: [[NY:%.*]] = xor i8 [[Y:%.*]], -1 +; CHECK-NEXT: [[CMPXY:%.*]] = icmp ult i8 [[NX]], [[NY]] +; CHECK-NEXT: [[MINXY:%.*]] = select i1 [[CMPXY]], i8 [[NX]], i8 [[NY]] +; CHECK-NEXT: [[SUBX:%.*]] = sub i8 [[NX]], [[MINXY]] +; CHECK-NEXT: [[SUBY:%.*]] = sub i8 [[NY]], [[MINXY]] +; CHECK-NEXT: call void @use8(i8 [[SUBX]]) +; CHECK-NEXT: call void @use8(i8 [[SUBY]]) +; CHECK-NEXT: ret i8 [[MINXY]] +; + %nx = xor i8 %x, -1 + %ny = xor i8 %y, -1 + %cmpxy = icmp ult i8 %nx, %ny + %minxy = select i1 %cmpxy, i8 %nx, i8 %ny + %subx = sub i8 %nx, %minxy + %suby = sub i8 %ny, %minxy + call void @use8(i8 %subx) + call void @use8(i8 %suby) + ret i8 %minxy +} + +define i8 @umin_not_sub_rev(i8 %x, i8 %y) { +; CHECK-LABEL: @umin_not_sub_rev( +; CHECK-NEXT: [[NX:%.*]] = xor i8 [[X:%.*]], -1 +; CHECK-NEXT: [[NY:%.*]] = xor i8 [[Y:%.*]], -1 +; CHECK-NEXT: [[CMPXY:%.*]] = icmp ult i8 [[NX]], [[NY]] +; CHECK-NEXT: [[MINXY:%.*]] = select i1 [[CMPXY]], i8 [[NX]], i8 [[NY]] +; CHECK-NEXT: [[SUBX:%.*]] = sub i8 [[MINXY]], [[NX]] +; CHECK-NEXT: [[SUBY:%.*]] = sub i8 [[MINXY]], [[NY]] +; CHECK-NEXT: call void @use8(i8 [[SUBX]]) +; CHECK-NEXT: call void @use8(i8 [[SUBY]]) +; CHECK-NEXT: ret i8 [[MINXY]] +; + %nx = xor i8 %x, -1 + %ny = xor i8 %y, -1 + %cmpxy = icmp ult i8 %nx, %ny + %minxy = select i1 %cmpxy, i8 %nx, i8 %ny + %subx = sub i8 %minxy, %nx + %suby = sub i8 %minxy, %ny + call void @use8(i8 %subx) + call void @use8(i8 %suby) + ret i8 %minxy +} + +define void @umin3_not_all_ops_extra_uses_invert_subs(i8 %x, i8 %y, i8 %z) { +; CHECK-LABEL: @umin3_not_all_ops_extra_uses_invert_subs( +; CHECK-NEXT: [[XN:%.*]] = xor i8 [[X:%.*]], -1 +; CHECK-NEXT: [[YN:%.*]] = xor i8 [[Y:%.*]], -1 +; CHECK-NEXT: [[ZN:%.*]] = xor i8 [[Z:%.*]], -1 +; CHECK-NEXT: [[CMPXZ:%.*]] = icmp ult i8 [[XN]], [[ZN]] +; CHECK-NEXT: [[MINXZ:%.*]] = select i1 [[CMPXZ]], i8 [[XN]], i8 [[ZN]] +; CHECK-NEXT: [[CMPXYZ:%.*]] = icmp ult i8 [[MINXZ]], [[YN]] +; CHECK-NEXT: [[MINXYZ:%.*]] = select i1 [[CMPXYZ]], i8 [[MINXZ]], i8 [[YN]] +; CHECK-NEXT: [[XMIN:%.*]] = sub i8 [[XN]], [[MINXYZ]] +; CHECK-NEXT: [[YMIN:%.*]] = sub i8 [[YN]], [[MINXYZ]] +; CHECK-NEXT: [[ZMIN:%.*]] = sub i8 [[ZN]], [[MINXYZ]] +; CHECK-NEXT: call void @use8(i8 [[MINXYZ]]) +; CHECK-NEXT: call void @use8(i8 [[XMIN]]) +; CHECK-NEXT: call void @use8(i8 [[YMIN]]) +; CHECK-NEXT: call void @use8(i8 [[ZMIN]]) +; CHECK-NEXT: ret void +; + %xn = xor i8 %x, -1 + %yn = xor i8 %y, -1 + %zn = xor i8 %z, -1 + %cmpxz = icmp ult i8 %xn, %zn + %minxz = select i1 %cmpxz, i8 %xn, i8 %zn + %cmpxyz = icmp ult i8 %minxz, %yn + %minxyz = select i1 %cmpxyz, i8 %minxz, i8 %yn + %xmin = sub i8 %xn, %minxyz + %ymin = sub i8 %yn, %minxyz + %zmin = sub i8 %zn, %minxyz + call void @use8(i8 %minxyz) + call void @use8(i8 %xmin) + call void @use8(i8 %ymin) + call void @use8(i8 %zmin) + ret void +} + +declare void @use8(i8) +declare void @use32(i32 %u) -- 2.7.4