From 12fcbcecffe1d84c9e0aa4c980f9053aad91c8e5 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Thu, 2 Apr 2020 12:02:37 -0400 Subject: [PATCH] [InstCombine] add tests for cmyk benchmark; NFC These are versions of a function that regressed with: rGf2fbdf76d8d0 That particular problem occurs with an instcombine-simplifycfg-instcombine sequence, but we can show that it exists within instcombine only with other variations of the pattern. --- .../Transforms/InstCombine/InstCombineCompares.cpp | 1 + llvm/test/Transforms/InstCombine/max-of-nots.ll | 96 ++++++++++++++++++++++ llvm/test/Transforms/PhaseOrdering/minmax.ll | 65 +++++++++++++++ 3 files changed, 162 insertions(+) create mode 100644 llvm/test/Transforms/PhaseOrdering/minmax.ll diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index 93312d4..bb7d0c9 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -5582,6 +5582,7 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) { if (Instruction *Res = foldICmpBitCast(I, Builder)) return Res; + // TODO: Hoist this above the min/max bailout. if (Instruction *R = foldICmpWithCastOp(I)) return R; diff --git a/llvm/test/Transforms/InstCombine/max-of-nots.ll b/llvm/test/Transforms/InstCombine/max-of-nots.ll index 7757c70..c6639ec 100644 --- a/llvm/test/Transforms/InstCombine/max-of-nots.ll +++ b/llvm/test/Transforms/InstCombine/max-of-nots.ll @@ -358,3 +358,99 @@ define <2 x i32> @max_of_min_vec(<2 x i32> %a) { ret <2 x i32> %s1 } +declare void @use(i8, i8, i8, i8) + +define void @cmyk(i8 %r, i8 %g, i8 %b) { +; CHECK-LABEL: @cmyk( +; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i8 [[R:%.*]], [[B:%.*]] +; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i8 [[R]], i8 [[B]] +; CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i8 [[TMP2]], [[G:%.*]] +; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP3]], i8 [[TMP2]], i8 [[G]] +; CHECK-NEXT: [[TMP5:%.*]] = xor i8 [[TMP4]], -1 +; CHECK-NEXT: [[CK:%.*]] = sub i8 [[TMP4]], [[R]] +; CHECK-NEXT: [[MK:%.*]] = sub i8 [[TMP4]], [[G]] +; CHECK-NEXT: [[YK:%.*]] = sub i8 [[TMP4]], [[B]] +; CHECK-NEXT: call void @use(i8 [[CK]], i8 [[MK]], i8 [[YK]], i8 [[TMP5]]) +; CHECK-NEXT: ret void +; + %notr = xor i8 %r, -1 + %notg = xor i8 %g, -1 + %notb = xor i8 %b, -1 + %cmp_gr = icmp slt i8 %g, %r + %cmp_br = icmp slt i8 %notr, %notb + %min_br = select i1 %cmp_br, i8 %notr, i8 %notb + %cmp_gb = icmp slt i8 %notg, %notb + %min_gb = select i1 %cmp_gb, i8 %notg, i8 %notb + %k = select i1 %cmp_gr, i8 %min_br, i8 %min_gb + %ck = sub i8 %notr, %k + %mk = sub i8 %notg, %k + %yk = sub i8 %notb, %k + call void @use(i8 %ck, i8 %mk, i8 %yk, i8 %k) + ret void +} + +define void @cmyk2(i8 %r, i8 %g, i8 %b) { +; CHECK-LABEL: @cmyk2( +; CHECK-NEXT: [[NOTR:%.*]] = xor i8 [[R:%.*]], -1 +; CHECK-NEXT: [[NOTG:%.*]] = xor i8 [[G:%.*]], -1 +; CHECK-NEXT: [[NOTB:%.*]] = xor i8 [[B:%.*]], -1 +; CHECK-NEXT: [[CMP_GR:%.*]] = icmp slt i8 [[G]], [[R]] +; CHECK-NEXT: [[CMP_BR:%.*]] = icmp slt i8 [[B]], [[R]] +; CHECK-NEXT: [[MIN_BR:%.*]] = select i1 [[CMP_BR]], i8 [[NOTR]], i8 [[NOTB]] +; CHECK-NEXT: [[CMP_BG:%.*]] = icmp slt i8 [[B]], [[G]] +; CHECK-NEXT: [[MIN_BG:%.*]] = select i1 [[CMP_BG]], i8 [[NOTG]], i8 [[NOTB]] +; CHECK-NEXT: [[K:%.*]] = select i1 [[CMP_GR]], i8 [[MIN_BR]], i8 [[MIN_BG]] +; CHECK-NEXT: [[CK:%.*]] = sub i8 [[NOTR]], [[K]] +; CHECK-NEXT: [[MK:%.*]] = sub i8 [[NOTG]], [[K]] +; CHECK-NEXT: [[YK:%.*]] = sub i8 [[NOTB]], [[K]] +; CHECK-NEXT: call void @use(i8 [[CK]], i8 [[MK]], i8 [[YK]], i8 [[K]]) +; CHECK-NEXT: ret void +; + %notr = xor i8 %r, -1 + %notg = xor i8 %g, -1 + %notb = xor i8 %b, -1 + %cmp_gr = icmp slt i8 %g, %r + %cmp_br = icmp slt i8 %b, %r + %min_br = select i1 %cmp_br, i8 %notr, i8 %notb + %cmp_bg = icmp slt i8 %b, %g + %min_bg = select i1 %cmp_bg, i8 %notg, i8 %notb + %k = select i1 %cmp_gr, i8 %min_br, i8 %min_bg + %ck = sub i8 %notr, %k + %mk = sub i8 %notg, %k + %yk = sub i8 %notb, %k + call void @use(i8 %ck, i8 %mk, i8 %yk, i8 %k) + ret void +} + +define void @cmyk3(i8 %r, i8 %g, i8 %b) { +; CHECK-LABEL: @cmyk3( +; CHECK-NEXT: [[NOTR:%.*]] = xor i8 [[R:%.*]], -1 +; CHECK-NEXT: [[NOTG:%.*]] = xor i8 [[G:%.*]], -1 +; CHECK-NEXT: [[NOTB:%.*]] = xor i8 [[B:%.*]], -1 +; CHECK-NEXT: [[CMP_GR:%.*]] = icmp ult i8 [[G]], [[R]] +; CHECK-NEXT: [[CMP_BR:%.*]] = icmp ult i8 [[B]], [[R]] +; CHECK-NEXT: [[SEL_RB:%.*]] = select i1 [[CMP_BR]], i8 [[NOTR]], i8 [[NOTB]] +; CHECK-NEXT: [[CMP_BG:%.*]] = icmp ult i8 [[B]], [[G]] +; CHECK-NEXT: [[SEL_GB:%.*]] = select i1 [[CMP_BG]], i8 [[NOTG]], i8 [[NOTB]] +; CHECK-NEXT: [[K:%.*]] = select i1 [[CMP_GR]], i8 [[SEL_RB]], i8 [[SEL_GB]] +; CHECK-NEXT: [[CK:%.*]] = sub i8 [[NOTR]], [[K]] +; CHECK-NEXT: [[MK:%.*]] = sub i8 [[NOTG]], [[K]] +; CHECK-NEXT: [[YK:%.*]] = sub i8 [[NOTB]], [[K]] +; CHECK-NEXT: tail call void @use(i8 [[CK]], i8 [[MK]], i8 [[YK]], i8 [[K]]) +; CHECK-NEXT: ret void +; + %notr = xor i8 %r, -1 + %notg = xor i8 %g, -1 + %notb = xor i8 %b, -1 + %cmp_gr = icmp ult i8 %g, %r + %cmp_br = icmp ult i8 %b, %r + %sel_rb = select i1 %cmp_br, i8 %notr, i8 %notb + %cmp_bg = icmp ult i8 %b, %g + %sel_gb = select i1 %cmp_bg, i8 %notg, i8 %notb + %k = select i1 %cmp_gr, i8 %sel_rb, i8 %sel_gb + %ck = sub i8 %notr, %k + %mk = sub i8 %notg, %k + %yk = sub i8 %notb, %k + tail call void @use(i8 %ck, i8 %mk, i8 %yk, i8 %k) + ret void +} diff --git a/llvm/test/Transforms/PhaseOrdering/minmax.ll b/llvm/test/Transforms/PhaseOrdering/minmax.ll new file mode 100644 index 0000000..6ddf491 --- /dev/null +++ b/llvm/test/Transforms/PhaseOrdering/minmax.ll @@ -0,0 +1,65 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -O1 -S < %s | FileCheck %s --check-prefixes=ANY,OLDPM +; RUN: opt -passes='default' -S < %s | FileCheck %s --check-prefixes=ANY,NEWPM + +; This is an important benchmark for color-space-conversion. +; It should reduce to contain only 1 'not' op. + +declare void @use(i8, i8, i8, i8) + +define void @cmyk(i8 %r, i8 %g, i8 %b) { +; ANY-LABEL: @cmyk( +; ANY-NEXT: entry: +; ANY-NEXT: [[TMP0:%.*]] = icmp sgt i8 [[R:%.*]], [[B:%.*]] +; ANY-NEXT: [[TMP1:%.*]] = select i1 [[TMP0]], i8 [[R]], i8 [[B]] +; ANY-NEXT: [[TMP2:%.*]] = icmp sgt i8 [[TMP1]], [[G:%.*]] +; ANY-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i8 [[TMP1]], i8 [[G]] +; ANY-NEXT: [[TMP4:%.*]] = xor i8 [[TMP3]], -1 +; ANY-NEXT: [[SUB31:%.*]] = sub i8 [[TMP3]], [[R]] +; ANY-NEXT: [[SUB35:%.*]] = sub i8 [[TMP3]], [[G]] +; ANY-NEXT: [[SUB39:%.*]] = sub i8 [[TMP3]], [[B]] +; ANY-NEXT: call void @use(i8 [[SUB31]], i8 [[SUB35]], i8 [[SUB39]], i8 [[TMP4]]) +; ANY-NEXT: ret void +; +entry: + %conv = sext i8 %r to i32 + %sub = sub nsw i32 255, %conv + %conv1 = trunc i32 %sub to i8 + %conv2 = sext i8 %g to i32 + %sub3 = sub nsw i32 255, %conv2 + %conv4 = trunc i32 %sub3 to i8 + %conv5 = sext i8 %b to i32 + %sub6 = sub nsw i32 255, %conv5 + %conv7 = trunc i32 %sub6 to i8 + %conv8 = sext i8 %conv1 to i32 + %conv9 = sext i8 %conv4 to i32 + %cmp = icmp slt i32 %conv8, %conv9 + br i1 %cmp, label %if.then, label %if.else + +if.then: + %conv12 = sext i8 %conv7 to i32 + %cmp13 = icmp slt i32 %conv8, %conv12 + %cond = select i1 %cmp13, i32 %conv8, i32 %conv12 + %conv17 = trunc i32 %cond to i8 + br label %if.end + +if.else: + %conv19 = sext i8 %conv7 to i32 + %cmp20 = icmp slt i32 %conv9, %conv19 + %cond27 = select i1 %cmp20, i32 %conv9, i32 %conv19 + %conv28 = trunc i32 %cond27 to i8 + br label %if.end + +if.end: + %k.0 = phi i8 [ %conv17, %if.then ], [ %conv28, %if.else ] + %conv30 = sext i8 %k.0 to i32 + %sub31 = sub nsw i32 %conv8, %conv30 + %conv32 = trunc i32 %sub31 to i8 + %sub35 = sub nsw i32 %conv9, %conv30 + %conv36 = trunc i32 %sub35 to i8 + %conv37 = sext i8 %conv7 to i32 + %sub39 = sub nsw i32 %conv37, %conv30 + %conv40 = trunc i32 %sub39 to i8 + call void @use(i8 %conv32, i8 %conv36, i8 %conv40, i8 %k.0) + ret void +} -- 2.7.4