; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 ; RUN: opt -passes=instcombine -S < %s | FileCheck %s declare void @escape(i16 %add) declare void @escape2(<2 x i16> %add) define void @numsignbits_shl_zext(i8 %x) { ; CHECK-LABEL: define void @numsignbits_shl_zext( ; CHECK-SAME: i8 [[X:%.*]]) { ; CHECK-NEXT: [[ASHR:%.*]] = ashr i8 [[X]], 5 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[ASHR]] to i16 ; CHECK-NEXT: [[NSB4:%.*]] = shl i16 [[ZEXT]], 10 ; CHECK-NEXT: [[ADD14:%.*]] = and i16 [[NSB4]], 15360 ; CHECK-NEXT: call void @escape(i16 [[ADD14]]) ; CHECK-NEXT: [[ADD13:%.*]] = and i16 [[NSB4]], 7168 ; CHECK-NEXT: call void @escape(i16 [[ADD13]]) ; CHECK-NEXT: [[ADD12:%.*]] = and i16 [[NSB4]], 3072 ; CHECK-NEXT: call void @escape(i16 [[ADD12]]) ; CHECK-NEXT: [[AND11:%.*]] = and i16 [[NSB4]], 2048 ; CHECK-NEXT: [[ADD11:%.*]] = add nsw i16 [[AND11]], [[NSB4]] ; CHECK-NEXT: call void @escape(i16 [[ADD11]]) ; CHECK-NEXT: ret void ; %ashr = ashr i8 %x, 5 %zext = zext i8 %ashr to i16 %nsb4 = shl i16 %zext, 10 ; Validate ComputeNumSignBits using this simplification: ; (A & 2^C1) + A => A & (2^C1 - 1) iff bit C1 in A is a sign bit ; 4 sign bits: Goal is to fold away the add for bits 12-14. %and14 = and i16 %nsb4, 16384 %add14 = add i16 %and14, %nsb4 call void @escape(i16 %add14) %and13 = and i16 %nsb4, 8192 %add13 = add i16 %and13, %nsb4 call void @escape(i16 %add13) %and12 = and i16 %nsb4, 4096 %add12 = add i16 %and12, %nsb4 call void @escape(i16 %add12) %and11 = and i16 %nsb4, 2048 %add11 = add i16 %and11, %nsb4 call void @escape(i16 %add11) ret void } define void @numsignbits_shl_zext_shift_amounr_matches_extend(i8 %x) { ; CHECK-LABEL: define void @numsignbits_shl_zext_shift_amounr_matches_extend( ; CHECK-SAME: i8 [[X:%.*]]) { ; CHECK-NEXT: [[ASHR:%.*]] = ashr i8 [[X]], 2 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[ASHR]] to i16 ; CHECK-NEXT: [[NSB3:%.*]] = shl nuw i16 [[ZEXT]], 8 ; CHECK-NEXT: [[ADD14:%.*]] = and i16 [[NSB3]], 16128 ; CHECK-NEXT: call void @escape(i16 [[ADD14]]) ; CHECK-NEXT: [[ADD13:%.*]] = and i16 [[NSB3]], 7936 ; CHECK-NEXT: call void @escape(i16 [[ADD13]]) ; CHECK-NEXT: [[AND12:%.*]] = and i16 [[NSB3]], 4096 ; CHECK-NEXT: [[ADD12:%.*]] = add nsw i16 [[AND12]], [[NSB3]] ; CHECK-NEXT: call void @escape(i16 [[ADD12]]) ; CHECK-NEXT: ret void ; %ashr = ashr i8 %x, 2 %zext = zext i8 %ashr to i16 %nsb3 = shl i16 %zext, 8 ; Validate ComputeNumSignBits using this simplification: ; (A & 2^C1) + A => A & (2^C1 - 1) iff bit C1 in A is a sign bit ; 3 sign bits: Goal is to fold away the add for bits 13-14. %and14 = and i16 %nsb3, 16384 %add14 = add i16 %and14, %nsb3 call void @escape(i16 %add14) %and13 = and i16 %nsb3, 8192 %add13 = add i16 %and13, %nsb3 call void @escape(i16 %add13) %and12 = and i16 %nsb3, 4096 %add12 = add i16 %and12, %nsb3 call void @escape(i16 %add12) ret void } define void @numsignbits_shl_zext_extended_bits_remains(i8 %x) { ; CHECK-LABEL: define void @numsignbits_shl_zext_extended_bits_remains( ; CHECK-SAME: i8 [[X:%.*]]) { ; CHECK-NEXT: [[ASHR:%.*]] = ashr i8 [[X]], 5 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[ASHR]] to i16 ; CHECK-NEXT: [[NSB1:%.*]] = shl nuw nsw i16 [[ZEXT]], 7 ; CHECK-NEXT: [[AND14:%.*]] = and i16 [[NSB1]], 16384 ; CHECK-NEXT: [[ADD14:%.*]] = add nuw i16 [[AND14]], [[NSB1]] ; CHECK-NEXT: call void @escape(i16 [[ADD14]]) ; CHECK-NEXT: ret void ; %ashr = ashr i8 %x, 5 %zext = zext i8 %ashr to i16 %nsb1 = shl i16 %zext, 7 ; Validate ComputeNumSignBits using this simplification: ; (A & 2^C1) + A => A & (2^C1 - 1) iff bit C1 in A is a sign bit ; 1 sign bit: The add can't be folded away here. %and14 = and i16 %nsb1, 16384 %add14 = add i16 %and14, %nsb1 call void @escape(i16 %add14) ret void } define void @numsignbits_shl_zext_all_bits_shifted_out(i8 %x) { ; CHECK-LABEL: define void @numsignbits_shl_zext_all_bits_shifted_out( ; CHECK-SAME: i8 [[X:%.*]]) { ; CHECK-NEXT: [[ASHR:%.*]] = lshr i8 [[X]], 5 ; CHECK-NEXT: [[ZEXT:%.*]] = zext nneg i8 [[ASHR]] to i16 ; CHECK-NEXT: [[NSB1:%.*]] = shl i16 [[ZEXT]], 14 ; CHECK-NEXT: [[AND14:%.*]] = and i16 [[NSB1]], 16384 ; CHECK-NEXT: [[ADD14:%.*]] = add i16 [[AND14]], [[NSB1]] ; CHECK-NEXT: call void @escape(i16 [[ADD14]]) ; CHECK-NEXT: ret void ; %ashr = ashr i8 %x, 5 %zext = zext i8 %ashr to i16 %nsb1 = shl i16 %zext, 14 ; Validate ComputeNumSignBits using this simplification: ; (A & 2^C1) + A => A & (2^C1 - 1) iff bit C1 in A is a sign bit ; 1 sign bit: The add can't be folded away here. %and14 = and i16 %nsb1, 16384 %add14 = add i16 %and14, %nsb1 call void @escape(i16 %add14) ret void } define void @numsignbits_shl_zext_vector(<2 x i8> %x) { ; CHECK-LABEL: define void @numsignbits_shl_zext_vector( ; CHECK-SAME: <2 x i8> [[X:%.*]]) { ; CHECK-NEXT: [[ASHR:%.*]] = ashr <2 x i8> [[X]], splat (i8 5) ; CHECK-NEXT: [[ZEXT:%.*]] = zext <2 x i8> [[ASHR]] to <2 x i16> ; CHECK-NEXT: [[NSB4:%.*]] = shl <2 x i16> [[ZEXT]], splat (i16 10) ; CHECK-NEXT: [[ADD14:%.*]] = and <2 x i16> [[NSB4]], splat (i16 15360) ; CHECK-NEXT: call void @escape2(<2 x i16> [[ADD14]]) ; CHECK-NEXT: [[ADD13:%.*]] = and <2 x i16> [[NSB4]], splat (i16 7168) ; CHECK-NEXT: call void @escape2(<2 x i16> [[ADD13]]) ; CHECK-NEXT: [[ADD12:%.*]] = and <2 x i16> [[NSB4]], splat (i16 3072) ; CHECK-NEXT: call void @escape2(<2 x i16> [[ADD12]]) ; CHECK-NEXT: [[AND11:%.*]] = and <2 x i16> [[NSB4]], splat (i16 2048) ; CHECK-NEXT: [[ADD11:%.*]] = add nsw <2 x i16> [[AND11]], [[NSB4]] ; CHECK-NEXT: call void @escape2(<2 x i16> [[ADD11]]) ; CHECK-NEXT: ret void ; %ashr = ashr <2 x i8> %x, %zext = zext <2 x i8> %ashr to <2 x i16> %nsb4 = shl <2 x i16> %zext, ; Validate ComputeNumSignBits using this simplification: ; (A & 2^C1) + A => A & (2^C1 - 1) iff bit C1 in A is a sign bit ; 4 sign bits: Goal is to fold away the add for bits 12-14. %and14 = and <2 x i16> %nsb4, %add14 = add <2 x i16> %and14, %nsb4 call void @escape2(<2 x i16> %add14) %and13 = and <2 x i16> %nsb4, %add13 = add <2 x i16> %and13, %nsb4 call void @escape2(<2 x i16> %add13) %and12 = and <2 x i16> %nsb4, %add12 = add <2 x i16> %and12, %nsb4 call void @escape2(<2 x i16> %add12) %and11 = and <2 x i16> %nsb4, %add11 = add <2 x i16> %and11, %nsb4 call void @escape2(<2 x i16> %add11) ret void }