From: Sanjay Patel Date: Fri, 20 Jan 2017 21:49:41 +0000 (+0000) Subject: [InstCombine] add tests to show missed canonicalization of min/max; NFC X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7d5b56cb3ecf29591e8c54b7230fdb0da09f7b35;p=llvm [InstCombine] add tests to show missed canonicalization of min/max; NFC Unfortunately, recognizing these in value tracking may cause us to hit a hack in InstCombiner::visitICmpInst() more often: http://lists.llvm.org/pipermail/llvm-dev/2017-January/109340.html ...but besides being the obviously Right Thing To Do, there's a clear codegen win from identifying these patterns for several targets. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@292655 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/test/Transforms/InstCombine/minmax-fold.ll b/test/Transforms/InstCombine/minmax-fold.ll index e39f7f491cb..ec838e25f31 100644 --- a/test/Transforms/InstCombine/minmax-fold.ll +++ b/test/Transforms/InstCombine/minmax-fold.ll @@ -339,3 +339,74 @@ define i32 @test75(i32 %x) { ret i32 %retval } +; The next 4 tests are value clamping with constants: +; https://llvm.org/bugs/show_bug.cgi?id=31693 + +; (X SMAX(SMIN(X, C2), C1) + +define i32 @clamp_signed1(i32 %x) { +; CHECK-LABEL: @clamp_signed1( +; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 %x, 255 +; CHECK-NEXT: [[MIN:%.*]] = select i1 [[CMP2]], i32 %x, i32 255 +; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 %x, 15 +; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP1]], i32 15, i32 [[MIN]] +; CHECK-NEXT: ret i32 [[R]] +; + %cmp2 = icmp slt i32 %x, 255 + %min = select i1 %cmp2, i32 %x, i32 255 + %cmp1 = icmp slt i32 %x, 15 + %r = select i1 %cmp1, i32 15, i32 %min + ret i32 %r +} + +; (X >s C1) ? C1 : SMAX(X, C2) ==> SMIN(SMAX(X, C2), C1) + +define i32 @clamp_signed2(i32 %x) { +; CHECK-LABEL: @clamp_signed2( +; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 %x, 15 +; CHECK-NEXT: [[MAX:%.*]] = select i1 [[CMP2]], i32 %x, i32 15 +; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 %x, 255 +; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP1]], i32 255, i32 [[MAX]] +; CHECK-NEXT: ret i32 [[R]] +; + %cmp2 = icmp sgt i32 %x, 15 + %max = select i1 %cmp2, i32 %x, i32 15 + %cmp1 = icmp sgt i32 %x, 255 + %r = select i1 %cmp1, i32 255, i32 %max + ret i32 %r +} + +; (X UMAX(UMIN(X, C2), C1) + +define i32 @clamp_unsigned1(i32 %x) { +; CHECK-LABEL: @clamp_unsigned1( +; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 %x, 255 +; CHECK-NEXT: [[MIN:%.*]] = select i1 [[CMP2]], i32 %x, i32 255 +; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 %x, 15 +; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP1]], i32 15, i32 [[MIN]] +; CHECK-NEXT: ret i32 [[R]] +; + %cmp2 = icmp ult i32 %x, 255 + %min = select i1 %cmp2, i32 %x, i32 255 + %cmp1 = icmp ult i32 %x, 15 + %r = select i1 %cmp1, i32 15, i32 %min + ret i32 %r +} + +; (X >u C1) ? C1 : UMAX(X, C2) ==> UMIN(UMAX(X, C2), C1) + +define i32 @clamp_unsigned2(i32 %x) { +; CHECK-LABEL: @clamp_unsigned2( +; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 %x, 15 +; CHECK-NEXT: [[MAX:%.*]] = select i1 [[CMP2]], i32 %x, i32 15 +; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i32 %x, 255 +; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP1]], i32 255, i32 [[MAX]] +; CHECK-NEXT: ret i32 [[R]] +; + %cmp2 = icmp ugt i32 %x, 15 + %max = select i1 %cmp2, i32 %x, i32 15 + %cmp1 = icmp ugt i32 %x, 255 + %r = select i1 %cmp1, i32 255, i32 %max + ret i32 %r +} +