diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp index aa547565bd085..e7a2f54f86809 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -1988,7 +1988,10 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) { // is not entirely arbitrary. For historical reasons, the backend may // recognize rotate left patterns but miss rotate right patterns. if (IID == Intrinsic::fshr) { - // fshr X, Y, C --> fshl X, Y, (BitWidth - C) + // fshr X, Y, C --> fshl X, Y, (BitWidth - C) if C is not zero. + if (!isKnownNonZero(ShAmtC, SQ.getWithInstruction(II))) + return nullptr; + Constant *LeftShiftC = ConstantExpr::getSub(WidthC, ShAmtC); Module *Mod = II->getModule(); Function *Fshl = Intrinsic::getDeclaration(Mod, Intrinsic::fshl, Ty); diff --git a/llvm/test/Transforms/InstCombine/fsh.ll b/llvm/test/Transforms/InstCombine/fsh.ll index 3bd44ece306b9..505a228367254 100644 --- a/llvm/test/Transforms/InstCombine/fsh.ll +++ b/llvm/test/Transforms/InstCombine/fsh.ll @@ -1002,10 +1002,9 @@ define <2 x i32> @fsh_unary_shuffle_ops_partial_widening(<3 x i32> %x, <2 x i32> ret <2 x i32> %r } -; FIXME: This is a miscompile. define <2 x i32> @fshr_vec_zero_elem(<2 x i32> %x, <2 x i32> %y) { ; CHECK-LABEL: @fshr_vec_zero_elem( -; CHECK-NEXT: [[FSH:%.*]] = call <2 x i32> @llvm.fshl.v2i32(<2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]], <2 x i32> ) +; CHECK-NEXT: [[FSH:%.*]] = call <2 x i32> @llvm.fshr.v2i32(<2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]], <2 x i32> ) ; CHECK-NEXT: ret <2 x i32> [[FSH]] ; %fsh = call <2 x i32> @llvm.fshr.v2i32(<2 x i32> %x, <2 x i32> %y, <2 x i32> )