| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6 |
| ; RUN: opt -passes=slp-vectorizer -S -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s |
| |
| ; Test for https://github.com/llvm/llvm-project/issues/209010. |
| ; The chain of "select i1 %x, i1 %y, i1 false" is an AND-reduction over 8 |
| ; icmp results. One operand of the reduced comparisons is demoted to i16, |
| ; but the i32 constant 58593 compared against it does not fit into a |
| ; signed i16 (it needs 17 significant bits), so it must not be truncated |
| ; to i16 (which would reinterpret it as the negative value -6943 and flip |
| ; the result of the signed comparison). |
| define i32 @test(i16 %c) { |
| ; CHECK-LABEL: define i32 @test( |
| ; CHECK-SAME: i16 [[C:%.*]]) { |
| ; CHECK-NEXT: [[ENTRY:.*:]] |
| ; CHECK-NEXT: [[CONV:%.*]] = sext i16 [[C]] to i32 |
| ; CHECK-NEXT: [[OR:%.*]] = or i32 0, 1 |
| ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[OR]], [[CONV]] |
| ; CHECK-NEXT: [[TMP0:%.*]] = trunc i32 [[OR]] to i16 |
| ; CHECK-NEXT: [[TMP1:%.*]] = insertelement <8 x i16> <i16 0, i16 0, i16 poison, i16 poison, i16 0, i16 0, i16 poison, i16 poison>, i16 [[TMP0]], i64 2 |
| ; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[XOR]] to i16 |
| ; CHECK-NEXT: [[TMP3:%.*]] = insertelement <8 x i16> [[TMP1]], i16 [[TMP2]], i64 3 |
| ; CHECK-NEXT: [[TMP4:%.*]] = shufflevector <8 x i16> [[TMP3]], <8 x i16> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 2, i32 3, i32 2, i32 4, i32 5> |
| ; CHECK-NEXT: [[TMP5:%.*]] = sext <8 x i16> [[TMP4]] to <8 x i32> |
| ; CHECK-NEXT: [[TMP6:%.*]] = icmp slt <8 x i32> [[TMP5]], <i32 1, i32 1, i32 58593, i32 58593, i32 58593, i32 58593, i32 1, i32 1> |
| ; CHECK-NEXT: [[TMP7:%.*]] = freeze <8 x i1> [[TMP6]] |
| ; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v8i1(<8 x i1> [[TMP7]]) |
| ; CHECK-NEXT: [[AND:%.*]] = select i1 [[CMP]], i32 1, i32 0 |
| ; CHECK-NEXT: ret i32 [[AND]] |
| ; |
| entry: |
| %conv = sext i16 %c to i32 |
| %cmp1 = icmp slt i32 0, 1 |
| %cmp2 = icmp slt i32 0, 1 |
| %sel1 = select i1 %cmp1, i1 %cmp2, i1 false |
| %or = or i32 0, 1 |
| %cmp3 = icmp slt i32 %or, 58593 |
| %sel2 = select i1 %sel1, i1 %cmp3, i1 false |
| %cmp4 = icmp slt i32 %or, 58593 |
| %sel3 = select i1 %sel2, i1 %cmp4, i1 false |
| %xor = xor i32 %or, %conv |
| %cmp5 = icmp slt i32 %xor, 58593 |
| %sel4 = select i1 %sel3, i1 %cmp5, i1 false |
| %cmp6 = icmp slt i32 %or, 58593 |
| %sel5 = select i1 %sel4, i1 %cmp6, i1 false |
| %cmp7 = icmp slt i32 0, 1 |
| %sel6 = select i1 %sel5, i1 %cmp7, i1 false |
| %cmp8 = icmp slt i32 0, 1 |
| %sel7 = select i1 %sel6, i1 %cmp8, i1 false |
| %and = select i1 %sel7, i32 1, i32 0 |
| ret i32 %and |
| } |