1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4define i1 @reduce_xor_self(<8 x i1> %x) { 5; CHECK-LABEL: @reduce_xor_self( 6; CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x i1> [[X:%.*]] to i8 7; CHECK-NEXT: [[TMP2:%.*]] = call range(i8 0, 9) i8 @llvm.ctpop.i8(i8 [[TMP1]]) 8; CHECK-NEXT: [[RES:%.*]] = trunc i8 [[TMP2]] to i1 9; CHECK-NEXT: ret i1 [[RES]] 10; 11 %res = call i1 @llvm.vector.reduce.xor.v8i32(<8 x i1> %x) 12 ret i1 %res 13} 14 15define i32 @reduce_xor_sext(<4 x i1> %x) { 16; CHECK-LABEL: @reduce_xor_sext( 17; CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i1> [[X:%.*]] to i4 18; CHECK-NEXT: [[TMP2:%.*]] = call range(i4 0, 5) i4 @llvm.ctpop.i4(i4 [[TMP1]]) 19; CHECK-NEXT: [[TMP3:%.*]] = trunc i4 [[TMP2]] to i1 20; CHECK-NEXT: [[RES:%.*]] = sext i1 [[TMP3]] to i32 21; CHECK-NEXT: ret i32 [[RES]] 22; 23 %sext = sext <4 x i1> %x to <4 x i32> 24 %res = call i32 @llvm.vector.reduce.xor.v4i32(<4 x i32> %sext) 25 ret i32 %res 26} 27 28define i64 @reduce_xor_zext(<8 x i1> %x) { 29; CHECK-LABEL: @reduce_xor_zext( 30; CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x i1> [[X:%.*]] to i8 31; CHECK-NEXT: [[TMP2:%.*]] = call range(i8 0, 9) i8 @llvm.ctpop.i8(i8 [[TMP1]]) 32; CHECK-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 1 33; CHECK-NEXT: [[RES:%.*]] = zext nneg i8 [[TMP3]] to i64 34; CHECK-NEXT: ret i64 [[RES]] 35; 36 %zext = zext <8 x i1> %x to <8 x i64> 37 %res = call i64 @llvm.vector.reduce.xor.v8i64(<8 x i64> %zext) 38 ret i64 %res 39} 40 41define i16 @reduce_xor_sext_same(<16 x i1> %x) { 42; CHECK-LABEL: @reduce_xor_sext_same( 43; CHECK-NEXT: [[TMP1:%.*]] = bitcast <16 x i1> [[X:%.*]] to i16 44; CHECK-NEXT: [[TMP2:%.*]] = call range(i16 0, 17) i16 @llvm.ctpop.i16(i16 [[TMP1]]) 45; CHECK-NEXT: [[TMP3:%.*]] = and i16 [[TMP2]], 1 46; CHECK-NEXT: [[SEXT:%.*]] = sub nsw i16 0, [[TMP3]] 47; CHECK-NEXT: ret i16 [[SEXT]] 48; 49 %sext = sext <16 x i1> %x to <16 x i16> 50 %res = call i16 @llvm.vector.reduce.xor.v16i16(<16 x i16> %sext) 51 ret i16 %res 52} 53 54define i8 @reduce_xor_zext_long(<128 x i1> %x) { 55; CHECK-LABEL: @reduce_xor_zext_long( 56; CHECK-NEXT: [[TMP1:%.*]] = bitcast <128 x i1> [[X:%.*]] to i128 57; CHECK-NEXT: [[TMP2:%.*]] = call range(i128 0, 129) i128 @llvm.ctpop.i128(i128 [[TMP1]]) 58; CHECK-NEXT: [[TMP3:%.*]] = trunc i128 [[TMP2]] to i1 59; CHECK-NEXT: [[RES:%.*]] = sext i1 [[TMP3]] to i8 60; CHECK-NEXT: ret i8 [[RES]] 61; 62 %sext = sext <128 x i1> %x to <128 x i8> 63 %res = call i8 @llvm.vector.reduce.xor.v128i8(<128 x i8> %sext) 64 ret i8 %res 65} 66 67@glob = external global i8, align 1 68define i8 @reduce_xor_zext_long_external_use(<128 x i1> %x) { 69; CHECK-LABEL: @reduce_xor_zext_long_external_use( 70; CHECK-NEXT: [[TMP1:%.*]] = bitcast <128 x i1> [[X:%.*]] to i128 71; CHECK-NEXT: [[TMP2:%.*]] = call range(i128 0, 129) i128 @llvm.ctpop.i128(i128 [[TMP1]]) 72; CHECK-NEXT: [[TMP3:%.*]] = trunc i128 [[TMP2]] to i1 73; CHECK-NEXT: [[RES:%.*]] = sext i1 [[TMP3]] to i8 74; CHECK-NEXT: [[TMP5:%.*]] = extractelement <128 x i1> [[X]], i64 0 75; CHECK-NEXT: [[EXT:%.*]] = sext i1 [[TMP5]] to i8 76; CHECK-NEXT: store i8 [[EXT]], ptr @glob, align 1 77; CHECK-NEXT: ret i8 [[RES]] 78; 79 %sext = sext <128 x i1> %x to <128 x i8> 80 %res = call i8 @llvm.vector.reduce.xor.v128i8(<128 x i8> %sext) 81 %ext = extractelement <128 x i8> %sext, i32 0 82 store i8 %ext, ptr @glob, align 1 83 ret i8 %res 84} 85 86@glob1 = external global i64, align 8 87define i64 @reduce_xor_zext_external_use(<8 x i1> %x) { 88; CHECK-LABEL: @reduce_xor_zext_external_use( 89; CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x i1> [[X:%.*]] to i8 90; CHECK-NEXT: [[TMP2:%.*]] = call range(i8 0, 9) i8 @llvm.ctpop.i8(i8 [[TMP1]]) 91; CHECK-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], 1 92; CHECK-NEXT: [[RES:%.*]] = zext nneg i8 [[TMP3]] to i64 93; CHECK-NEXT: [[TMP4:%.*]] = extractelement <8 x i1> [[X]], i64 0 94; CHECK-NEXT: [[EXT:%.*]] = zext i1 [[TMP4]] to i64 95; CHECK-NEXT: store i64 [[EXT]], ptr @glob1, align 8 96; CHECK-NEXT: ret i64 [[RES]] 97; 98 %zext = zext <8 x i1> %x to <8 x i64> 99 %res = call i64 @llvm.vector.reduce.xor.v8i64(<8 x i64> %zext) 100 %ext = extractelement <8 x i64> %zext, i32 0 101 store i64 %ext, ptr @glob1, align 8 102 ret i64 %res 103} 104 105declare i1 @llvm.vector.reduce.xor.v8i32(<8 x i1> %a) 106declare i32 @llvm.vector.reduce.xor.v4i32(<4 x i32> %a) 107declare i64 @llvm.vector.reduce.xor.v8i64(<8 x i64> %a) 108declare i16 @llvm.vector.reduce.xor.v16i16(<16 x i16> %a) 109declare i8 @llvm.vector.reduce.xor.v128i8(<128 x i8> %a) 110