From: Sanjay Patel Date: Mon, 13 May 2019 17:02:26 +0000 (+0000) Subject: [InstCombine] add tests for rotates with narrow shift amount (PR20750); NFC X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=14f6bfdda506a82ca58b66ae617336262c75feb1;p=llvm [InstCombine] add tests for rotates with narrow shift amount (PR20750); NFC git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@360601 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/test/Transforms/InstCombine/rotate.ll b/test/Transforms/InstCombine/rotate.ll index 6e11c68df92..984dac1cbc1 100644 --- a/test/Transforms/InstCombine/rotate.ll +++ b/test/Transforms/InstCombine/rotate.ll @@ -703,3 +703,49 @@ define i32 @rotl_constant_expr(i32 %shamt) { %r = or i32 %shr, shl (i32 ptrtoint (i8* @external_global to i32), i32 11) ret i32 %r } + +; PR20750 - https://bugs.llvm.org/show_bug.cgi?id=20750 +; This IR corresponds to C source where the shift amount is a smaller type than the rotated value: +; unsigned int rotate32_doubleand1(unsigned int v, unsigned char r) { r = r & 31; return (v << r) | (v >> (((32 - r)) & 31)); } + +define i32 @rotateleft32_doubleand1(i32 %v, i8 %r) { +; CHECK-LABEL: @rotateleft32_doubleand1( +; CHECK-NEXT: [[M:%.*]] = and i8 [[R:%.*]], 31 +; CHECK-NEXT: [[Z:%.*]] = zext i8 [[M]] to i32 +; CHECK-NEXT: [[NEG:%.*]] = sub nsw i32 0, [[Z]] +; CHECK-NEXT: [[AND2:%.*]] = and i32 [[NEG]], 31 +; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[V:%.*]], [[Z]] +; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[V]], [[AND2]] +; CHECK-NEXT: [[OR:%.*]] = or i32 [[SHR]], [[SHL]] +; CHECK-NEXT: ret i32 [[OR]] +; + %m = and i8 %r, 31 + %z = zext i8 %m to i32 + %neg = sub nsw i32 0, %z + %and2 = and i32 %neg, 31 + %shl = shl i32 %v, %z + %shr = lshr i32 %v, %and2 + %or = or i32 %shr, %shl + ret i32 %or +} + +define i32 @rotateright32_doubleand1(i32 %v, i16 %r) { +; CHECK-LABEL: @rotateright32_doubleand1( +; CHECK-NEXT: [[M:%.*]] = and i16 [[R:%.*]], 31 +; CHECK-NEXT: [[Z:%.*]] = zext i16 [[M]] to i32 +; CHECK-NEXT: [[NEG:%.*]] = sub nsw i32 0, [[Z]] +; CHECK-NEXT: [[AND2:%.*]] = and i32 [[NEG]], 31 +; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[V:%.*]], [[AND2]] +; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[V]], [[Z]] +; CHECK-NEXT: [[OR:%.*]] = or i32 [[SHR]], [[SHL]] +; CHECK-NEXT: ret i32 [[OR]] +; + %m = and i16 %r, 31 + %z = zext i16 %m to i32 + %neg = sub nsw i32 0, %z + %and2 = and i32 %neg, 31 + %shl = shl i32 %v, %and2 + %shr = lshr i32 %v, %z + %or = or i32 %shr, %shl + ret i32 %or +}