Index: lib/Analysis/InstructionSimplify.cpp =================================================================== --- lib/Analysis/InstructionSimplify.cpp +++ lib/Analysis/InstructionSimplify.cpp @@ -1226,6 +1226,11 @@ Value *X; if (match(Op0, m_Exact(m_Shr(m_Value(X), m_Specific(Op1))))) return X; + + // shl nuw i8 C, %x -> C iff C has sign bit set. + if (isNUW && match(Op0, m_Negative())) + return Op0; + return nullptr; } Index: test/Transforms/InstSimplify/constantfold-shl-nuw-C-to-C.ll =================================================================== --- test/Transforms/InstSimplify/constantfold-shl-nuw-C-to-C.ll +++ test/Transforms/InstSimplify/constantfold-shl-nuw-C-to-C.ll @@ -9,8 +9,7 @@ define i8 @shl_nuw (i8 %x) { ; CHECK-LABEL: @shl_nuw( -; CHECK-NEXT: [[RET:%.*]] = shl nuw i8 -1, [[X:%.*]] -; CHECK-NEXT: ret i8 [[RET]] +; CHECK-NEXT: ret i8 -1 ; %ret = shl nuw i8 -1, %x ; nuw here means that %x can only be 0 @@ -19,8 +18,7 @@ define i8 @shl_nuw_nsw (i8 %x) { ; CHECK-LABEL: @shl_nuw_nsw( -; CHECK-NEXT: [[RET:%.*]] = shl nuw nsw i8 -1, [[X:%.*]] -; CHECK-NEXT: ret i8 [[RET]] +; CHECK-NEXT: ret i8 -1 ; %ret = shl nuw nsw i8 -1, %x ; nuw here means that %x can only be 0 @@ -29,8 +27,7 @@ define i8 @shl_128 (i8 %x) { ; CHECK-LABEL: @shl_128( -; CHECK-NEXT: [[RET:%.*]] = shl nuw i8 -128, [[X:%.*]] -; CHECK-NEXT: ret i8 [[RET]] +; CHECK-NEXT: ret i8 -128 ; %ret = shl nuw i8 128, %x ; 128 == 1<<7 == just the sign bit is set @@ -43,8 +40,7 @@ define <2 x i8> @shl_vec(<2 x i8> %x) { ; CHECK-LABEL: @shl_vec( -; CHECK-NEXT: [[RET:%.*]] = shl nuw <2 x i8> , [[X:%.*]] -; CHECK-NEXT: ret <2 x i8> [[RET]] +; CHECK-NEXT: ret <2 x i8> ; %ret = shl nuw <2 x i8> , %x ret <2 x i8> %ret @@ -52,8 +48,7 @@ define <3 x i8> @shl_vec_undef(<3 x i8> %x) { ; CHECK-LABEL: @shl_vec_undef( -; CHECK-NEXT: [[RET:%.*]] = shl nuw <3 x i8> , [[X:%.*]] -; CHECK-NEXT: ret <3 x i8> [[RET]] +; CHECK-NEXT: ret <3 x i8> ; %ret = shl nuw <3 x i8> , %x ret <3 x i8> %ret @@ -61,8 +56,7 @@ define <2 x i8> @shl_vec_nonsplat(<2 x i8> %x) { ; CHECK-LABEL: @shl_vec_nonsplat( -; CHECK-NEXT: [[RET:%.*]] = shl nuw <2 x i8> , [[X:%.*]] -; CHECK-NEXT: ret <2 x i8> [[RET]] +; CHECK-NEXT: ret <2 x i8> ; %ret = shl nuw <2 x i8> , %x ret <2 x i8> %ret