| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py |
| ; RUN: opt < %s -passes=instcombine -S | FileCheck %s |
| |
| declare void @use(i1) |
| declare void @use32(i32) |
| |
| define i1 @PR1817_1(i32 %X) { |
| ; CHECK-LABEL: @PR1817_1( |
| ; CHECK-NEXT: [[B:%.*]] = icmp ult i32 [[X:%.*]], 10 |
| ; CHECK-NEXT: ret i1 [[B]] |
| ; |
| %A = icmp slt i32 %X, 10 |
| %B = icmp ult i32 %X, 10 |
| %C = and i1 %A, %B |
| ret i1 %C |
| } |
| |
| define i1 @PR1817_1_logical(i32 %X) { |
| ; CHECK-LABEL: @PR1817_1_logical( |
| ; CHECK-NEXT: [[B:%.*]] = icmp ult i32 [[X:%.*]], 10 |
| ; CHECK-NEXT: ret i1 [[B]] |
| ; |
| %A = icmp slt i32 %X, 10 |
| %B = icmp ult i32 %X, 10 |
| %C = select i1 %A, i1 %B, i1 false |
| ret i1 %C |
| } |
| |
| define i1 @PR1817_2(i32 %X) { |
| ; CHECK-LABEL: @PR1817_2( |
| ; CHECK-NEXT: [[A:%.*]] = icmp slt i32 [[X:%.*]], 10 |
| ; CHECK-NEXT: ret i1 [[A]] |
| ; |
| %A = icmp slt i32 %X, 10 |
| %B = icmp ult i32 %X, 10 |
| %C = or i1 %A, %B |
| ret i1 %C |
| } |
| |
| define i1 @PR1817_2_logical(i32 %X) { |
| ; CHECK-LABEL: @PR1817_2_logical( |
| ; CHECK-NEXT: [[A:%.*]] = icmp slt i32 [[X:%.*]], 10 |
| ; CHECK-NEXT: ret i1 [[A]] |
| ; |
| %A = icmp slt i32 %X, 10 |
| %B = icmp ult i32 %X, 10 |
| %C = select i1 %A, i1 true, i1 %B |
| ret i1 %C |
| } |
| |
| define i1 @PR2330(i32 %a, i32 %b) { |
| ; CHECK-LABEL: @PR2330( |
| ; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[B:%.*]], [[A:%.*]] |
| ; CHECK-NEXT: [[AND:%.*]] = icmp ult i32 [[TMP1]], 8 |
| ; CHECK-NEXT: ret i1 [[AND]] |
| ; |
| %cmp1 = icmp ult i32 %a, 8 |
| %cmp2 = icmp ult i32 %b, 8 |
| %and = and i1 %cmp2, %cmp1 |
| ret i1 %and |
| } |
| |
| define i1 @PR2330_logical(i32 %a, i32 %b) { |
| ; CHECK-LABEL: @PR2330_logical( |
| ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[A:%.*]], 8 |
| ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[B:%.*]], 8 |
| ; CHECK-NEXT: [[AND:%.*]] = select i1 [[CMP2]], i1 [[CMP1]], i1 false |
| ; CHECK-NEXT: ret i1 [[AND]] |
| ; |
| %cmp1 = icmp ult i32 %a, 8 |
| %cmp2 = icmp ult i32 %b, 8 |
| %and = select i1 %cmp2, i1 %cmp1, i1 false |
| ret i1 %and |
| } |
| |
| ; if LHSC and RHSC differ only by one bit: |
| ; (X == C1 || X == C2) -> (X & ~(C1 ^ C2)) == C1 (C1 has 1 less set bit) |
| ; PR14708: https://bugs.llvm.org/show_bug.cgi?id=14708 |
| |
| define i1 @or_eq_with_one_bit_diff_constants1(i32 %x) { |
| ; CHECK-LABEL: @or_eq_with_one_bit_diff_constants1( |
| ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -2 |
| ; CHECK-NEXT: [[OR:%.*]] = icmp eq i32 [[TMP1]], 50 |
| ; CHECK-NEXT: ret i1 [[OR]] |
| ; |
| %cmp1 = icmp eq i32 %x, 50 |
| %cmp2 = icmp eq i32 %x, 51 |
| %or = or i1 %cmp1, %cmp2 |
| ret i1 %or |
| } |
| |
| define i1 @or_eq_with_one_bit_diff_constants1_logical(i32 %x) { |
| ; CHECK-LABEL: @or_eq_with_one_bit_diff_constants1_logical( |
| ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -2 |
| ; CHECK-NEXT: [[OR:%.*]] = icmp eq i32 [[TMP1]], 50 |
| ; CHECK-NEXT: ret i1 [[OR]] |
| ; |
| %cmp1 = icmp eq i32 %x, 50 |
| %cmp2 = icmp eq i32 %x, 51 |
| %or = select i1 %cmp1, i1 true, i1 %cmp2 |
| ret i1 %or |
| } |
| |
| ; (X != C1 && X != C2) -> (X & ~(C1 ^ C2)) != C1 (C1 has 1 less set bit) |
| |
| define i1 @and_ne_with_one_bit_diff_constants1(i32 %x) { |
| ; CHECK-LABEL: @and_ne_with_one_bit_diff_constants1( |
| ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -52 |
| ; CHECK-NEXT: [[AND:%.*]] = icmp ult i32 [[TMP1]], -2 |
| ; CHECK-NEXT: ret i1 [[AND]] |
| ; |
| %cmp1 = icmp ne i32 %x, 51 |
| %cmp2 = icmp ne i32 %x, 50 |
| %and = and i1 %cmp1, %cmp2 |
| ret i1 %and |
| } |
| |
| define i1 @and_ne_with_one_bit_diff_constants1_logical(i32 %x) { |
| ; CHECK-LABEL: @and_ne_with_one_bit_diff_constants1_logical( |
| ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -52 |
| ; CHECK-NEXT: [[AND:%.*]] = icmp ult i32 [[TMP1]], -2 |
| ; CHECK-NEXT: ret i1 [[AND]] |
| ; |
| %cmp1 = icmp ne i32 %x, 51 |
| %cmp2 = icmp ne i32 %x, 50 |
| %and = select i1 %cmp1, i1 %cmp2, i1 false |
| ret i1 %and |
| } |
| |
| ; The constants are not necessarily off-by-one, just off-by-one-bit. |
| |
| define i1 @or_eq_with_one_bit_diff_constants2(i32 %x) { |
| ; CHECK-LABEL: @or_eq_with_one_bit_diff_constants2( |
| ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -33 |
| ; CHECK-NEXT: [[OR:%.*]] = icmp eq i32 [[TMP1]], 65 |
| ; CHECK-NEXT: ret i1 [[OR]] |
| ; |
| %cmp1 = icmp eq i32 %x, 97 |
| %cmp2 = icmp eq i32 %x, 65 |
| %or = or i1 %cmp1, %cmp2 |
| ret i1 %or |
| } |
| |
| define i1 @or_eq_with_one_bit_diff_constants2_logical(i32 %x) { |
| ; CHECK-LABEL: @or_eq_with_one_bit_diff_constants2_logical( |
| ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], -33 |
| ; CHECK-NEXT: [[OR:%.*]] = icmp eq i32 [[TMP1]], 65 |
| ; CHECK-NEXT: ret i1 [[OR]] |
| ; |
| %cmp1 = icmp eq i32 %x, 97 |
| %cmp2 = icmp eq i32 %x, 65 |
| %or = select i1 %cmp1, i1 true, i1 %cmp2 |
| ret i1 %or |
| } |
| |
| define i1 @and_ne_with_one_bit_diff_constants2(i19 %x) { |
| ; CHECK-LABEL: @and_ne_with_one_bit_diff_constants2( |
| ; CHECK-NEXT: [[TMP1:%.*]] = and i19 [[X:%.*]], -129 |
| ; CHECK-NEXT: [[AND:%.*]] = icmp ne i19 [[TMP1]], 65 |
| ; CHECK-NEXT: ret i1 [[AND]] |
| ; |
| %cmp1 = icmp ne i19 %x, 65 |
| %cmp2 = icmp ne i19 %x, 193 |
| %and = and i1 %cmp1, %cmp2 |
| ret i1 %and |
| } |
| |
| define i1 @and_ne_with_one_bit_diff_constants2_logical(i19 %x) { |
| ; CHECK-LABEL: @and_ne_with_one_bit_diff_constants2_logical( |
| ; CHECK-NEXT: [[TMP1:%.*]] = and i19 [[X:%.*]], -129 |
| ; CHECK-NEXT: [[AND:%.*]] = icmp ne i19 [[TMP1]], 65 |
| ; CHECK-NEXT: ret i1 [[AND]] |
| ; |
| %cmp1 = icmp ne i19 %x, 65 |
| %cmp2 = icmp ne i19 %x, 193 |
| %and = select i1 %cmp1, i1 %cmp2, i1 false |
| ret i1 %and |
| } |
| |
| ; Make sure the constants are treated as unsigned when comparing them. |
| |
| define i1 @or_eq_with_one_bit_diff_constants3(i8 %x) { |
| ; CHECK-LABEL: @or_eq_with_one_bit_diff_constants3( |
| ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], 127 |
| ; CHECK-NEXT: [[OR:%.*]] = icmp eq i8 [[TMP1]], 126 |
| ; CHECK-NEXT: ret i1 [[OR]] |
| ; |
| %cmp1 = icmp eq i8 %x, 254 |
| %cmp2 = icmp eq i8 %x, 126 |
| %or = or i1 %cmp1, %cmp2 |
| ret i1 %or |
| } |
| |
| define i1 @or_eq_with_one_bit_diff_constants3_logical(i8 %x) { |
| ; CHECK-LABEL: @or_eq_with_one_bit_diff_constants3_logical( |
| ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], 127 |
| ; CHECK-NEXT: [[OR:%.*]] = icmp eq i8 [[TMP1]], 126 |
| ; CHECK-NEXT: ret i1 [[OR]] |
| ; |
| %cmp1 = icmp eq i8 %x, 254 |
| %cmp2 = icmp eq i8 %x, 126 |
| %or = select i1 %cmp1, i1 true, i1 %cmp2 |
| ret i1 %or |
| } |
| |
| define i1 @and_ne_with_one_bit_diff_constants3(i8 %x) { |
| ; CHECK-LABEL: @and_ne_with_one_bit_diff_constants3( |
| ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], 127 |
| ; CHECK-NEXT: [[AND:%.*]] = icmp ne i8 [[TMP1]], 65 |
| ; CHECK-NEXT: ret i1 [[AND]] |
| ; |
| %cmp1 = icmp ne i8 %x, 65 |
| %cmp2 = icmp ne i8 %x, 193 |
| %and = and i1 %cmp1, %cmp2 |
| ret i1 %and |
| } |
| |
| define i1 @and_ne_with_one_bit_diff_constants3_logical(i8 %x) { |
| ; CHECK-LABEL: @and_ne_with_one_bit_diff_constants3_logical( |
| ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], 127 |
| ; CHECK-NEXT: [[AND:%.*]] = icmp ne i8 [[TMP1]], 65 |
| ; CHECK-NEXT: ret i1 [[AND]] |
| ; |
| %cmp1 = icmp ne i8 %x, 65 |
| %cmp2 = icmp ne i8 %x, 193 |
| %and = select i1 %cmp1, i1 %cmp2, i1 false |
| ret i1 %and |
| } |
| |
| ; Use an 'add' to eliminate an icmp if the constants are off-by-one (not off-by-one-bit). |
| ; (X == 13 | X == 14) -> X-13 <u 2 |
| |
| define i1 @or_eq_with_diff_one(i8 %x) { |
| ; CHECK-LABEL: @or_eq_with_diff_one( |
| ; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[X:%.*]], -13 |
| ; CHECK-NEXT: [[OR:%.*]] = icmp ult i8 [[TMP1]], 2 |
| ; CHECK-NEXT: ret i1 [[OR]] |
| ; |
| %cmp1 = icmp eq i8 %x, 13 |
| %cmp2 = icmp eq i8 %x, 14 |
| %or = or i1 %cmp1, %cmp2 |
| ret i1 %or |
| } |
| |
| define i1 @or_eq_with_diff_one_logical(i8 %x) { |
| ; CHECK-LABEL: @or_eq_with_diff_one_logical( |
| ; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[X:%.*]], -13 |
| ; CHECK-NEXT: [[OR:%.*]] = icmp ult i8 [[TMP1]], 2 |
| ; CHECK-NEXT: ret i1 [[OR]] |
| ; |
| %cmp1 = icmp eq i8 %x, 13 |
| %cmp2 = icmp eq i8 %x, 14 |
| %or = select i1 %cmp1, i1 true, i1 %cmp2 |
| ret i1 %or |
| } |
| |
| ; (X != 40 | X != 39) -> X-39 >u 1 |
| |
| define i1 @and_ne_with_diff_one(i32 %x) { |
| ; CHECK-LABEL: @and_ne_with_diff_one( |
| ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -41 |
| ; CHECK-NEXT: [[AND:%.*]] = icmp ult i32 [[TMP1]], -2 |
| ; CHECK-NEXT: ret i1 [[AND]] |
| ; |
| %cmp1 = icmp ne i32 %x, 40 |
| %cmp2 = icmp ne i32 %x, 39 |
| %and = and i1 %cmp1, %cmp2 |
| ret i1 %and |
| } |
| |
| define i1 @and_ne_with_diff_one_logical(i32 %x) { |
| ; CHECK-LABEL: @and_ne_with_diff_one_logical( |
| ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -41 |
| ; CHECK-NEXT: [[AND:%.*]] = icmp ult i32 [[TMP1]], -2 |
| ; CHECK-NEXT: ret i1 [[AND]] |
| ; |
| %cmp1 = icmp ne i32 %x, 40 |
| %cmp2 = icmp ne i32 %x, 39 |
| %and = select i1 %cmp1, i1 %cmp2, i1 false |
| ret i1 %and |
| } |
| |
| ; Make sure the constants are treated as signed when comparing them. |
| ; PR32524: https://bugs.llvm.org/show_bug.cgi?id=32524 |
| |
| define i1 @or_eq_with_diff_one_signed(i32 %x) { |
| ; CHECK-LABEL: @or_eq_with_diff_one_signed( |
| ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], 1 |
| ; CHECK-NEXT: [[OR:%.*]] = icmp ult i32 [[TMP1]], 2 |
| ; CHECK-NEXT: ret i1 [[OR]] |
| ; |
| %cmp1 = icmp eq i32 %x, 0 |
| %cmp2 = icmp eq i32 %x, -1 |
| %or = or i1 %cmp1, %cmp2 |
| ret i1 %or |
| } |
| |
| define i1 @or_eq_with_diff_one_signed_logical(i32 %x) { |
| ; CHECK-LABEL: @or_eq_with_diff_one_signed_logical( |
| ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], 1 |
| ; CHECK-NEXT: [[OR:%.*]] = icmp ult i32 [[TMP1]], 2 |
| ; CHECK-NEXT: ret i1 [[OR]] |
| ; |
| %cmp1 = icmp eq i32 %x, 0 |
| %cmp2 = icmp eq i32 %x, -1 |
| %or = select i1 %cmp1, i1 true, i1 %cmp2 |
| ret i1 %or |
| } |
| |
| define i1 @and_ne_with_diff_one_signed(i64 %x) { |
| ; CHECK-LABEL: @and_ne_with_diff_one_signed( |
| ; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[X:%.*]], -1 |
| ; CHECK-NEXT: [[AND:%.*]] = icmp ult i64 [[TMP1]], -2 |
| ; CHECK-NEXT: ret i1 [[AND]] |
| ; |
| %cmp1 = icmp ne i64 %x, -1 |
| %cmp2 = icmp ne i64 %x, 0 |
| %and = and i1 %cmp1, %cmp2 |
| ret i1 %and |
| } |
| |
| define i1 @and_ne_with_diff_one_signed_logical(i64 %x) { |
| ; CHECK-LABEL: @and_ne_with_diff_one_signed_logical( |
| ; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[X:%.*]], -1 |
| ; CHECK-NEXT: [[AND:%.*]] = icmp ult i64 [[TMP1]], -2 |
| ; CHECK-NEXT: ret i1 [[AND]] |
| ; |
| %cmp1 = icmp ne i64 %x, -1 |
| %cmp2 = icmp ne i64 %x, 0 |
| %and = select i1 %cmp1, i1 %cmp2, i1 false |
| ret i1 %and |
| } |
| |
| ; Vectors with splat constants get the same folds. |
| |
| define <2 x i1> @or_eq_with_one_bit_diff_constants2_splatvec(<2 x i32> %x) { |
| ; CHECK-LABEL: @or_eq_with_one_bit_diff_constants2_splatvec( |
| ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 -33, i32 -33> |
| ; CHECK-NEXT: [[OR:%.*]] = icmp eq <2 x i32> [[TMP1]], <i32 65, i32 65> |
| ; CHECK-NEXT: ret <2 x i1> [[OR]] |
| ; |
| %cmp1 = icmp eq <2 x i32> %x, <i32 97, i32 97> |
| %cmp2 = icmp eq <2 x i32> %x, <i32 65, i32 65> |
| %or = or <2 x i1> %cmp1, %cmp2 |
| ret <2 x i1> %or |
| } |
| |
| define <2 x i1> @and_ne_with_diff_one_splatvec(<2 x i32> %x) { |
| ; CHECK-LABEL: @and_ne_with_diff_one_splatvec( |
| ; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i32> [[X:%.*]], <i32 -41, i32 -41> |
| ; CHECK-NEXT: [[AND:%.*]] = icmp ult <2 x i32> [[TMP1]], <i32 -2, i32 -2> |
| ; CHECK-NEXT: ret <2 x i1> [[AND]] |
| ; |
| %cmp1 = icmp ne <2 x i32> %x, <i32 40, i32 40> |
| %cmp2 = icmp ne <2 x i32> %x, <i32 39, i32 39> |
| %and = and <2 x i1> %cmp1, %cmp2 |
| ret <2 x i1> %and |
| } |
| |
| ; This is a fuzzer-generated test that would assert because |
| ; we'd get into foldAndOfICmps() without running InstSimplify |
| ; on an 'and' that should have been killed. It's not obvious |
| ; why, but removing anything hides the bug, hence the long test. |
| |
| define void @simplify_before_foldAndOfICmps(ptr %p) { |
| ; CHECK-LABEL: @simplify_before_foldAndOfICmps( |
| ; CHECK-NEXT: [[A8:%.*]] = alloca i16, align 2 |
| ; CHECK-NEXT: [[L7:%.*]] = load i16, ptr [[A8]], align 2 |
| ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i16 [[L7]], -1 |
| ; CHECK-NEXT: [[B11:%.*]] = zext i1 [[TMP1]] to i16 |
| ; CHECK-NEXT: [[C10:%.*]] = icmp ugt i16 [[L7]], [[B11]] |
| ; CHECK-NEXT: [[C5:%.*]] = icmp slt i16 [[L7]], 1 |
| ; CHECK-NEXT: [[C7:%.*]] = icmp slt i16 [[L7]], 0 |
| ; CHECK-NEXT: [[B15:%.*]] = xor i1 [[C7]], [[C10]] |
| ; CHECK-NEXT: [[C6:%.*]] = xor i1 [[B15]], true |
| ; CHECK-NEXT: [[TMP2:%.*]] = and i1 [[C5]], [[C6]] |
| ; CHECK-NEXT: [[C3:%.*]] = and i1 [[TMP2]], [[C10]] |
| ; CHECK-NEXT: [[TMP3:%.*]] = xor i1 [[C10]], true |
| ; CHECK-NEXT: [[C18:%.*]] = or i1 [[C7]], [[TMP3]] |
| ; CHECK-NEXT: [[TMP4:%.*]] = sext i1 [[C3]] to i64 |
| ; CHECK-NEXT: [[G26:%.*]] = getelementptr i1, ptr null, i64 [[TMP4]] |
| ; CHECK-NEXT: store i16 [[L7]], ptr [[P:%.*]], align 2 |
| ; CHECK-NEXT: store i1 [[C18]], ptr [[P]], align 1 |
| ; CHECK-NEXT: store ptr [[G26]], ptr [[P]], align 8 |
| ; CHECK-NEXT: ret void |
| ; |
| %A8 = alloca i16 |
| %L7 = load i16, ptr %A8 |
| %G21 = getelementptr i16, ptr %A8, i8 -1 |
| %B11 = udiv i16 %L7, -1 |
| %G4 = getelementptr i16, ptr %A8, i16 %B11 |
| %L2 = load i16, ptr %G4 |
| %L = load i16, ptr %G4 |
| %B23 = mul i16 %B11, %B11 |
| %L4 = load i16, ptr %A8 |
| %B21 = sdiv i16 %L7, %L4 |
| %B7 = sub i16 0, %B21 |
| %B18 = mul i16 %B23, %B7 |
| %C10 = icmp ugt i16 %L, %B11 |
| %B20 = and i16 %L7, %L2 |
| %B1 = mul i1 %C10, true |
| %C5 = icmp sle i16 %B21, %L |
| %C11 = icmp ule i16 %B21, %L |
| %C7 = icmp slt i16 %B20, 0 |
| %B29 = srem i16 %L4, %B18 |
| %B15 = add i1 %C7, %C10 |
| %B19 = add i1 %C11, %B15 |
| %C6 = icmp sge i1 %C11, %B19 |
| %B33 = or i16 %B29, %L4 |
| %C13 = icmp uge i1 %C5, %B1 |
| %C3 = icmp ult i1 %C13, %C6 |
| store i16 undef, ptr %G21 |
| %C18 = icmp ule i1 %C10, %C7 |
| %G26 = getelementptr i1, ptr null, i1 %C3 |
| store i16 %B33, ptr %p |
| store i1 %C18, ptr %p |
| store ptr %G26, ptr %p |
| ret void |
| } |
| |
| define i1 @PR42691_1(i32 %x) { |
| ; CHECK-LABEL: @PR42691_1( |
| ; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[X:%.*]], 2147483646 |
| ; CHECK-NEXT: ret i1 [[C]] |
| ; |
| %c1 = icmp slt i32 %x, 0 |
| %c2 = icmp eq i32 %x, 2147483647 |
| %c = or i1 %c1, %c2 |
| ret i1 %c |
| } |
| |
| define i1 @PR42691_1_logical(i32 %x) { |
| ; CHECK-LABEL: @PR42691_1_logical( |
| ; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[X:%.*]], 2147483646 |
| ; CHECK-NEXT: ret i1 [[C]] |
| ; |
| %c1 = icmp slt i32 %x, 0 |
| %c2 = icmp eq i32 %x, 2147483647 |
| %c = select i1 %c1, i1 true, i1 %c2 |
| ret i1 %c |
| } |
| |
| define i1 @PR42691_2(i32 %x) { |
| ; CHECK-LABEL: @PR42691_2( |
| ; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[X:%.*]], -2 |
| ; CHECK-NEXT: ret i1 [[C]] |
| ; |
| %c1 = icmp ult i32 %x, 2147483648 |
| %c2 = icmp eq i32 %x, 4294967295 |
| %c = or i1 %c1, %c2 |
| ret i1 %c |
| } |
| |
| define i1 @PR42691_2_logical(i32 %x) { |
| ; CHECK-LABEL: @PR42691_2_logical( |
| ; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[X:%.*]], -2 |
| ; CHECK-NEXT: ret i1 [[C]] |
| ; |
| %c1 = icmp ult i32 %x, 2147483648 |
| %c2 = icmp eq i32 %x, 4294967295 |
| %c = select i1 %c1, i1 true, i1 %c2 |
| ret i1 %c |
| } |
| |
| define i1 @PR42691_3(i32 %x) { |
| ; CHECK-LABEL: @PR42691_3( |
| ; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[X:%.*]], -2147483647 |
| ; CHECK-NEXT: ret i1 [[C]] |
| ; |
| %c1 = icmp sge i32 %x, 0 |
| %c2 = icmp eq i32 %x, -2147483648 |
| %c = or i1 %c1, %c2 |
| ret i1 %c |
| } |
| |
| define i1 @PR42691_3_logical(i32 %x) { |
| ; CHECK-LABEL: @PR42691_3_logical( |
| ; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[X:%.*]], -2147483647 |
| ; CHECK-NEXT: ret i1 [[C]] |
| ; |
| %c1 = icmp sge i32 %x, 0 |
| %c2 = icmp eq i32 %x, -2147483648 |
| %c = select i1 %c1, i1 true, i1 %c2 |
| ret i1 %c |
| } |
| |
| define i1 @PR42691_4(i32 %x) { |
| ; CHECK-LABEL: @PR42691_4( |
| ; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[X:%.*]], 1 |
| ; CHECK-NEXT: ret i1 [[C]] |
| ; |
| %c1 = icmp uge i32 %x, 2147483648 |
| %c2 = icmp eq i32 %x, 0 |
| %c = or i1 %c1, %c2 |
| ret i1 %c |
| } |
| |
| define i1 @PR42691_4_logical(i32 %x) { |
| ; CHECK-LABEL: @PR42691_4_logical( |
| ; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[X:%.*]], 1 |
| ; CHECK-NEXT: ret i1 [[C]] |
| ; |
| %c1 = icmp uge i32 %x, 2147483648 |
| %c2 = icmp eq i32 %x, 0 |
| %c = select i1 %c1, i1 true, i1 %c2 |
| ret i1 %c |
| } |
| |
| define i1 @PR42691_5(i32 %x) { |
| ; CHECK-LABEL: @PR42691_5( |
| ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -2147483647 |
| ; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[TMP1]], -2147483646 |
| ; CHECK-NEXT: ret i1 [[C]] |
| ; |
| %c1 = icmp slt i32 %x, 1 |
| %c2 = icmp eq i32 %x, 2147483647 |
| %c = or i1 %c1, %c2 |
| ret i1 %c |
| } |
| |
| define i1 @PR42691_5_logical(i32 %x) { |
| ; CHECK-LABEL: @PR42691_5_logical( |
| ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -2147483647 |
| ; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[TMP1]], -2147483646 |
| ; CHECK-NEXT: ret i1 [[C]] |
| ; |
| %c1 = icmp slt i32 %x, 1 |
| %c2 = icmp eq i32 %x, 2147483647 |
| %c = select i1 %c1, i1 true, i1 %c2 |
| ret i1 %c |
| } |
| |
| define i1 @PR42691_6(i32 %x) { |
| ; CHECK-LABEL: @PR42691_6( |
| ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], 1 |
| ; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[TMP1]], -2147483646 |
| ; CHECK-NEXT: ret i1 [[C]] |
| ; |
| %c1 = icmp ult i32 %x, 2147483649 |
| %c2 = icmp eq i32 %x, 4294967295 |
| %c = or i1 %c1, %c2 |
| ret i1 %c |
| } |
| |
| define i1 @PR42691_6_logical(i32 %x) { |
| ; CHECK-LABEL: @PR42691_6_logical( |
| ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], 1 |
| ; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[TMP1]], -2147483646 |
| ; CHECK-NEXT: ret i1 [[C]] |
| ; |
| %c1 = icmp ult i32 %x, 2147483649 |
| %c2 = icmp eq i32 %x, 4294967295 |
| %c = select i1 %c1, i1 true, i1 %c2 |
| ret i1 %c |
| } |
| |
| define i1 @PR42691_7(i32 %x) { |
| ; CHECK-LABEL: @PR42691_7( |
| ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -1 |
| ; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[TMP1]], 0 |
| ; CHECK-NEXT: ret i1 [[C]] |
| ; |
| %c1 = icmp uge i32 %x, 2147483649 |
| %c2 = icmp eq i32 %x, 0 |
| %c = or i1 %c1, %c2 |
| ret i1 %c |
| } |
| |
| define i1 @PR42691_7_logical(i32 %x) { |
| ; CHECK-LABEL: @PR42691_7_logical( |
| ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -1 |
| ; CHECK-NEXT: [[C:%.*]] = icmp slt i32 [[TMP1]], 0 |
| ; CHECK-NEXT: ret i1 [[C]] |
| ; |
| %c1 = icmp uge i32 %x, 2147483649 |
| %c2 = icmp eq i32 %x, 0 |
| %c = select i1 %c1, i1 true, i1 %c2 |
| ret i1 %c |
| } |
| |
| define i1 @PR42691_8(i32 %x) { |
| ; CHECK-LABEL: @PR42691_8( |
| ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], 2147483647 |
| ; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[TMP1]], -2147483635 |
| ; CHECK-NEXT: ret i1 [[C]] |
| ; |
| %c1 = icmp slt i32 %x, 14 |
| %c2 = icmp ne i32 %x, -2147483648 |
| %c = and i1 %c1, %c2 |
| ret i1 %c |
| } |
| |
| define i1 @PR42691_8_logical(i32 %x) { |
| ; CHECK-LABEL: @PR42691_8_logical( |
| ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], 2147483647 |
| ; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[TMP1]], -2147483635 |
| ; CHECK-NEXT: ret i1 [[C]] |
| ; |
| %c1 = icmp slt i32 %x, 14 |
| %c2 = icmp ne i32 %x, -2147483648 |
| %c = select i1 %c1, i1 %c2, i1 false |
| ret i1 %c |
| } |
| |
| define i1 @PR42691_9(i32 %x) { |
| ; CHECK-LABEL: @PR42691_9( |
| ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -14 |
| ; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[TMP1]], 2147483633 |
| ; CHECK-NEXT: ret i1 [[C]] |
| ; |
| %c1 = icmp sgt i32 %x, 13 |
| %c2 = icmp ne i32 %x, 2147483647 |
| %c = and i1 %c1, %c2 |
| ret i1 %c |
| } |
| |
| define i1 @PR42691_9_logical(i32 %x) { |
| ; CHECK-LABEL: @PR42691_9_logical( |
| ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -14 |
| ; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[TMP1]], 2147483633 |
| ; CHECK-NEXT: ret i1 [[C]] |
| ; |
| %c1 = icmp sgt i32 %x, 13 |
| %c2 = icmp ne i32 %x, 2147483647 |
| %c = select i1 %c1, i1 %c2, i1 false |
| ret i1 %c |
| } |
| |
| define i1 @PR42691_10(i32 %x) { |
| ; CHECK-LABEL: @PR42691_10( |
| ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -14 |
| ; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[TMP1]], -15 |
| ; CHECK-NEXT: ret i1 [[C]] |
| ; |
| %c1 = icmp ugt i32 %x, 13 |
| %c2 = icmp ne i32 %x, 4294967295 |
| %c = and i1 %c1, %c2 |
| ret i1 %c |
| } |
| |
| define i1 @PR42691_10_logical(i32 %x) { |
| ; CHECK-LABEL: @PR42691_10_logical( |
| ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X:%.*]], -14 |
| ; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[TMP1]], -15 |
| ; CHECK-NEXT: ret i1 [[C]] |
| ; |
| %c1 = icmp ugt i32 %x, 13 |
| %c2 = icmp ne i32 %x, 4294967295 |
| %c = select i1 %c1, i1 %c2, i1 false |
| ret i1 %c |
| } |
| |
| define i1 @substitute_constant_and_eq_eq(i8 %x, i8 %y) { |
| ; CHECK-LABEL: @substitute_constant_and_eq_eq( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42 |
| ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[Y:%.*]], 42 |
| ; CHECK-NEXT: [[R:%.*]] = and i1 [[C1]], [[TMP1]] |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %c1 = icmp eq i8 %x, 42 |
| %c2 = icmp eq i8 %x, %y |
| %r = and i1 %c1, %c2 |
| ret i1 %r |
| } |
| |
| define i1 @substitute_constant_and_eq_eq_logical(i8 %x, i8 %y) { |
| ; CHECK-LABEL: @substitute_constant_and_eq_eq_logical( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42 |
| ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[Y:%.*]], 42 |
| ; CHECK-NEXT: [[R:%.*]] = select i1 [[C1]], i1 [[TMP1]], i1 false |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %c1 = icmp eq i8 %x, 42 |
| %c2 = icmp eq i8 %x, %y |
| %r = select i1 %c1, i1 %c2, i1 false |
| ret i1 %r |
| } |
| |
| define i1 @substitute_constant_and_eq_eq_commute(i8 %x, i8 %y) { |
| ; CHECK-LABEL: @substitute_constant_and_eq_eq_commute( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42 |
| ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[Y:%.*]], 42 |
| ; CHECK-NEXT: [[R:%.*]] = and i1 [[C1]], [[TMP1]] |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %c1 = icmp eq i8 %x, 42 |
| %c2 = icmp eq i8 %x, %y |
| %r = and i1 %c2, %c1 |
| ret i1 %r |
| } |
| |
| define i1 @substitute_constant_and_eq_eq_commute_logical(i8 %x, i8 %y) { |
| ; CHECK-LABEL: @substitute_constant_and_eq_eq_commute_logical( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42 |
| ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[Y:%.*]], 42 |
| ; CHECK-NEXT: [[R:%.*]] = and i1 [[C1]], [[TMP1]] |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %c1 = icmp eq i8 %x, 42 |
| %c2 = icmp eq i8 %x, %y |
| %r = select i1 %c2, i1 %c1, i1 false |
| ret i1 %r |
| } |
| |
| define i1 @substitute_constant_and_eq_ugt_swap(i8 %x, i8 %y) { |
| ; CHECK-LABEL: @substitute_constant_and_eq_ugt_swap( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42 |
| ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i8 [[Y:%.*]], 42 |
| ; CHECK-NEXT: [[R:%.*]] = and i1 [[C1]], [[TMP1]] |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %c1 = icmp eq i8 %x, 42 |
| %c2 = icmp ugt i8 %y, %x |
| %r = and i1 %c2, %c1 |
| ret i1 %r |
| } |
| |
| define i1 @substitute_constant_and_eq_ugt_swap_logical(i8 %x, i8 %y) { |
| ; CHECK-LABEL: @substitute_constant_and_eq_ugt_swap_logical( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42 |
| ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i8 [[Y:%.*]], 42 |
| ; CHECK-NEXT: [[R:%.*]] = and i1 [[C1]], [[TMP1]] |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %c1 = icmp eq i8 %x, 42 |
| %c2 = icmp ugt i8 %y, %x |
| %r = select i1 %c2, i1 %c1, i1 false |
| ret i1 %r |
| } |
| |
| define <2 x i1> @substitute_constant_and_eq_ne_vec(<2 x i8> %x, <2 x i8> %y) { |
| ; CHECK-LABEL: @substitute_constant_and_eq_ne_vec( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq <2 x i8> [[X:%.*]], <i8 42, i8 97> |
| ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <2 x i8> [[Y:%.*]], <i8 42, i8 97> |
| ; CHECK-NEXT: [[R:%.*]] = and <2 x i1> [[C1]], [[TMP1]] |
| ; CHECK-NEXT: ret <2 x i1> [[R]] |
| ; |
| %c1 = icmp eq <2 x i8> %x, <i8 42, i8 97> |
| %c2 = icmp ne <2 x i8> %x, %y |
| %r = and <2 x i1> %c1, %c2 |
| ret <2 x i1> %r |
| } |
| |
| define <2 x i1> @substitute_constant_and_eq_ne_vec_logical(<2 x i8> %x, <2 x i8> %y) { |
| ; CHECK-LABEL: @substitute_constant_and_eq_ne_vec_logical( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq <2 x i8> [[X:%.*]], <i8 42, i8 97> |
| ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <2 x i8> [[Y:%.*]], <i8 42, i8 97> |
| ; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[C1]], <2 x i1> [[TMP1]], <2 x i1> zeroinitializer |
| ; CHECK-NEXT: ret <2 x i1> [[R]] |
| ; |
| %c1 = icmp eq <2 x i8> %x, <i8 42, i8 97> |
| %c2 = icmp ne <2 x i8> %x, %y |
| %r = select <2 x i1> %c1, <2 x i1> %c2, <2 x i1> zeroinitializer |
| ret <2 x i1> %r |
| } |
| |
| define i1 @substitute_constant_and_eq_sgt_use(i8 %x, i8 %y) { |
| ; CHECK-LABEL: @substitute_constant_and_eq_sgt_use( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42 |
| ; CHECK-NEXT: call void @use(i1 [[C1]]) |
| ; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i8 [[Y:%.*]], 42 |
| ; CHECK-NEXT: [[R:%.*]] = and i1 [[C1]], [[TMP1]] |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %c1 = icmp eq i8 %x, 42 |
| call void @use(i1 %c1) |
| %c2 = icmp sgt i8 %x, %y |
| %r = and i1 %c2, %c1 |
| ret i1 %r |
| } |
| |
| define i1 @substitute_constant_and_eq_sgt_use_logical(i8 %x, i8 %y) { |
| ; CHECK-LABEL: @substitute_constant_and_eq_sgt_use_logical( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42 |
| ; CHECK-NEXT: call void @use(i1 [[C1]]) |
| ; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i8 [[Y:%.*]], 42 |
| ; CHECK-NEXT: [[R:%.*]] = and i1 [[C1]], [[TMP1]] |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %c1 = icmp eq i8 %x, 42 |
| call void @use(i1 %c1) |
| %c2 = icmp sgt i8 %x, %y |
| %r = select i1 %c2, i1 %c1, i1 false |
| ret i1 %r |
| } |
| |
| ; Negative test - extra use |
| |
| define i1 @substitute_constant_and_eq_sgt_use2(i8 %x, i8 %y) { |
| ; CHECK-LABEL: @substitute_constant_and_eq_sgt_use2( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42 |
| ; CHECK-NEXT: [[C2:%.*]] = icmp sgt i8 [[X]], [[Y:%.*]] |
| ; CHECK-NEXT: call void @use(i1 [[C2]]) |
| ; CHECK-NEXT: [[R:%.*]] = and i1 [[C2]], [[C1]] |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %c1 = icmp eq i8 %x, 42 |
| %c2 = icmp sgt i8 %x, %y |
| call void @use(i1 %c2) |
| %r = and i1 %c2, %c1 |
| ret i1 %r |
| } |
| |
| define i1 @substitute_constant_and_eq_sgt_use2_logical(i8 %x, i8 %y) { |
| ; CHECK-LABEL: @substitute_constant_and_eq_sgt_use2_logical( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42 |
| ; CHECK-NEXT: [[C2:%.*]] = icmp sgt i8 [[X]], [[Y:%.*]] |
| ; CHECK-NEXT: call void @use(i1 [[C2]]) |
| ; CHECK-NEXT: [[R:%.*]] = and i1 [[C2]], [[C1]] |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %c1 = icmp eq i8 %x, 42 |
| %c2 = icmp sgt i8 %x, %y |
| call void @use(i1 %c2) |
| %r = select i1 %c2, i1 %c1, i1 false |
| ret i1 %r |
| } |
| |
| ; Extra use does not prevent transform if the expression simplifies: |
| ; X == MAX && X < Y --> false |
| |
| define i1 @slt_and_max(i8 %x, i8 %y) { |
| ; CHECK-LABEL: @slt_and_max( |
| ; CHECK-NEXT: [[C2:%.*]] = icmp slt i8 [[X:%.*]], [[Y:%.*]] |
| ; CHECK-NEXT: call void @use(i1 [[C2]]) |
| ; CHECK-NEXT: ret i1 false |
| ; |
| %c1 = icmp eq i8 %x, 127 |
| %c2 = icmp slt i8 %x, %y |
| call void @use(i1 %c2) |
| %r = and i1 %c2, %c1 |
| ret i1 %r |
| } |
| |
| define i1 @slt_and_max_logical(i8 %x, i8 %y) { |
| ; CHECK-LABEL: @slt_and_max_logical( |
| ; CHECK-NEXT: [[C2:%.*]] = icmp slt i8 [[X:%.*]], [[Y:%.*]] |
| ; CHECK-NEXT: call void @use(i1 [[C2]]) |
| ; CHECK-NEXT: ret i1 false |
| ; |
| %c1 = icmp eq i8 %x, 127 |
| %c2 = icmp slt i8 %x, %y |
| call void @use(i1 %c2) |
| %r = select i1 %c2, i1 %c1, i1 false |
| ret i1 %r |
| } |
| |
| ; Extra use does not prevent transform if the expression simplifies: |
| ; X == MAX && X >= Y --> X == MAX |
| |
| define i1 @sge_and_max(i8 %x, i8 %y) { |
| ; CHECK-LABEL: @sge_and_max( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[X:%.*]], 127 |
| ; CHECK-NEXT: [[C2:%.*]] = icmp sge i8 [[X]], [[Y:%.*]] |
| ; CHECK-NEXT: call void @use(i1 [[C2]]) |
| ; CHECK-NEXT: ret i1 [[C1]] |
| ; |
| %c1 = icmp eq i8 %x, 127 |
| %c2 = icmp sge i8 %x, %y |
| call void @use(i1 %c2) |
| %r = and i1 %c2, %c1 |
| ret i1 %r |
| } |
| |
| define i1 @sge_and_max_logical(i8 %x, i8 %y) { |
| ; CHECK-LABEL: @sge_and_max_logical( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[X:%.*]], 127 |
| ; CHECK-NEXT: [[C2:%.*]] = icmp sge i8 [[X]], [[Y:%.*]] |
| ; CHECK-NEXT: call void @use(i1 [[C2]]) |
| ; CHECK-NEXT: ret i1 [[C1]] |
| ; |
| %c1 = icmp eq i8 %x, 127 |
| %c2 = icmp sge i8 %x, %y |
| call void @use(i1 %c2) |
| %r = select i1 %c2, i1 %c1, i1 false |
| ret i1 %r |
| } |
| |
| define i1 @substitute_constant_and_ne_ugt_swap(i8 %x, i8 %y) { |
| ; CHECK-LABEL: @substitute_constant_and_ne_ugt_swap( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp ne i8 [[X:%.*]], 42 |
| ; CHECK-NEXT: [[C2:%.*]] = icmp ugt i8 [[Y:%.*]], [[X]] |
| ; CHECK-NEXT: [[R:%.*]] = and i1 [[C2]], [[C1]] |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %c1 = icmp ne i8 %x, 42 |
| %c2 = icmp ugt i8 %y, %x |
| %r = and i1 %c2, %c1 |
| ret i1 %r |
| } |
| |
| define i1 @substitute_constant_and_ne_ugt_swap_logical(i8 %x, i8 %y) { |
| ; CHECK-LABEL: @substitute_constant_and_ne_ugt_swap_logical( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp ne i8 [[X:%.*]], 42 |
| ; CHECK-NEXT: [[C2:%.*]] = icmp ugt i8 [[Y:%.*]], [[X]] |
| ; CHECK-NEXT: [[R:%.*]] = and i1 [[C2]], [[C1]] |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %c1 = icmp ne i8 %x, 42 |
| %c2 = icmp ugt i8 %y, %x |
| %r = select i1 %c2, i1 %c1, i1 false |
| ret i1 %r |
| } |
| |
| define i1 @substitute_constant_or_ne_swap_sle(i8 %x, i8 %y) { |
| ; CHECK-LABEL: @substitute_constant_or_ne_swap_sle( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp ne i8 [[X:%.*]], 42 |
| ; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i8 [[Y:%.*]], 43 |
| ; CHECK-NEXT: [[R:%.*]] = or i1 [[C1]], [[TMP1]] |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %c1 = icmp ne i8 %x, 42 |
| %c2 = icmp sle i8 %y, %x |
| %r = or i1 %c1, %c2 |
| ret i1 %r |
| } |
| |
| define i1 @substitute_constant_or_ne_swap_sle_logical(i8 %x, i8 %y) { |
| ; CHECK-LABEL: @substitute_constant_or_ne_swap_sle_logical( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp ne i8 [[X:%.*]], 42 |
| ; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i8 [[Y:%.*]], 43 |
| ; CHECK-NEXT: [[R:%.*]] = select i1 [[C1]], i1 true, i1 [[TMP1]] |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %c1 = icmp ne i8 %x, 42 |
| %c2 = icmp sle i8 %y, %x |
| %r = select i1 %c1, i1 true, i1 %c2 |
| ret i1 %r |
| } |
| |
| define i1 @substitute_constant_or_ne_uge_commute(i8 %x, i8 %y) { |
| ; CHECK-LABEL: @substitute_constant_or_ne_uge_commute( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp ne i8 [[X:%.*]], 42 |
| ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i8 [[Y:%.*]], 43 |
| ; CHECK-NEXT: [[R:%.*]] = or i1 [[C1]], [[TMP1]] |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %c1 = icmp ne i8 %x, 42 |
| %c2 = icmp uge i8 %x, %y |
| %r = or i1 %c2, %c1 |
| ret i1 %r |
| } |
| |
| define i1 @substitute_constant_or_ne_uge_commute_logical(i8 %x, i8 %y) { |
| ; CHECK-LABEL: @substitute_constant_or_ne_uge_commute_logical( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp ne i8 [[X:%.*]], 42 |
| ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i8 [[Y:%.*]], 43 |
| ; CHECK-NEXT: [[R:%.*]] = or i1 [[C1]], [[TMP1]] |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %c1 = icmp ne i8 %x, 42 |
| %c2 = icmp uge i8 %x, %y |
| %r = select i1 %c2, i1 true, i1 %c1 |
| ret i1 %r |
| } |
| |
| ; Negative test - not safe to substitute vector constant with undef element |
| |
| define <2 x i1> @substitute_constant_or_ne_slt_swap_vec(<2 x i8> %x, <2 x i8> %y) { |
| ; CHECK-LABEL: @substitute_constant_or_ne_slt_swap_vec( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp ne <2 x i8> [[X:%.*]], <i8 42, i8 undef> |
| ; CHECK-NEXT: [[C2:%.*]] = icmp slt <2 x i8> [[Y:%.*]], [[X]] |
| ; CHECK-NEXT: [[R:%.*]] = or <2 x i1> [[C1]], [[C2]] |
| ; CHECK-NEXT: ret <2 x i1> [[R]] |
| ; |
| %c1 = icmp ne <2 x i8> %x, <i8 42, i8 undef> |
| %c2 = icmp slt <2 x i8> %y, %x |
| %r = or <2 x i1> %c1, %c2 |
| ret <2 x i1> %r |
| } |
| |
| define <2 x i1> @substitute_constant_or_ne_slt_swap_vec_logical(<2 x i8> %x, <2 x i8> %y) { |
| ; CHECK-LABEL: @substitute_constant_or_ne_slt_swap_vec_logical( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp ne <2 x i8> [[X:%.*]], <i8 42, i8 undef> |
| ; CHECK-NEXT: [[C2:%.*]] = icmp slt <2 x i8> [[Y:%.*]], [[X]] |
| ; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[C1]], <2 x i1> <i1 true, i1 true>, <2 x i1> [[C2]] |
| ; CHECK-NEXT: ret <2 x i1> [[R]] |
| ; |
| %c1 = icmp ne <2 x i8> %x, <i8 42, i8 undef> |
| %c2 = icmp slt <2 x i8> %y, %x |
| %r = select <2 x i1> %c1, <2 x i1> <i1 true, i1 true>, <2 x i1> %c2 |
| ret <2 x i1> %r |
| } |
| |
| define i1 @substitute_constant_or_eq_swap_ne(i8 %x, i8 %y) { |
| ; CHECK-LABEL: @substitute_constant_or_eq_swap_ne( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42 |
| ; CHECK-NEXT: [[C2:%.*]] = icmp ne i8 [[Y:%.*]], [[X]] |
| ; CHECK-NEXT: [[R:%.*]] = or i1 [[C1]], [[C2]] |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %c1 = icmp eq i8 %x, 42 |
| %c2 = icmp ne i8 %y, %x |
| %r = or i1 %c1, %c2 |
| ret i1 %r |
| } |
| |
| define i1 @substitute_constant_or_eq_swap_ne_logical(i8 %x, i8 %y) { |
| ; CHECK-LABEL: @substitute_constant_or_eq_swap_ne_logical( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42 |
| ; CHECK-NEXT: [[C2:%.*]] = icmp ne i8 [[Y:%.*]], [[X]] |
| ; CHECK-NEXT: [[R:%.*]] = select i1 [[C1]], i1 true, i1 [[C2]] |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %c1 = icmp eq i8 %x, 42 |
| %c2 = icmp ne i8 %y, %x |
| %r = select i1 %c1, i1 true, i1 %c2 |
| ret i1 %r |
| } |
| |
| define i1 @substitute_constant_or_ne_sge_use(i8 %x, i8 %y) { |
| ; CHECK-LABEL: @substitute_constant_or_ne_sge_use( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp ne i8 [[X:%.*]], 42 |
| ; CHECK-NEXT: call void @use(i1 [[C1]]) |
| ; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i8 [[Y:%.*]], 43 |
| ; CHECK-NEXT: [[R:%.*]] = or i1 [[C1]], [[TMP1]] |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %c1 = icmp ne i8 %x, 42 |
| call void @use(i1 %c1) |
| %c2 = icmp sge i8 %x, %y |
| %r = or i1 %c2, %c1 |
| ret i1 %r |
| } |
| |
| define i1 @substitute_constant_or_ne_sge_use_logical(i8 %x, i8 %y) { |
| ; CHECK-LABEL: @substitute_constant_or_ne_sge_use_logical( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp ne i8 [[X:%.*]], 42 |
| ; CHECK-NEXT: call void @use(i1 [[C1]]) |
| ; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i8 [[Y:%.*]], 43 |
| ; CHECK-NEXT: [[R:%.*]] = or i1 [[C1]], [[TMP1]] |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %c1 = icmp ne i8 %x, 42 |
| call void @use(i1 %c1) |
| %c2 = icmp sge i8 %x, %y |
| %r = select i1 %c2, i1 true, i1 %c1 |
| ret i1 %r |
| } |
| |
| ; Negative test - extra use |
| |
| define i1 @substitute_constant_or_ne_ule_use2(i8 %x, i8 %y) { |
| ; CHECK-LABEL: @substitute_constant_or_ne_ule_use2( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp ne i8 [[X:%.*]], 42 |
| ; CHECK-NEXT: [[C2:%.*]] = icmp ule i8 [[X]], [[Y:%.*]] |
| ; CHECK-NEXT: call void @use(i1 [[C2]]) |
| ; CHECK-NEXT: [[R:%.*]] = or i1 [[C2]], [[C1]] |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %c1 = icmp ne i8 %x, 42 |
| %c2 = icmp ule i8 %x, %y |
| call void @use(i1 %c2) |
| %r = or i1 %c2, %c1 |
| ret i1 %r |
| } |
| |
| define i1 @substitute_constant_or_ne_ule_use2_logical(i8 %x, i8 %y) { |
| ; CHECK-LABEL: @substitute_constant_or_ne_ule_use2_logical( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp ne i8 [[X:%.*]], 42 |
| ; CHECK-NEXT: [[C2:%.*]] = icmp ule i8 [[X]], [[Y:%.*]] |
| ; CHECK-NEXT: call void @use(i1 [[C2]]) |
| ; CHECK-NEXT: [[R:%.*]] = or i1 [[C2]], [[C1]] |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %c1 = icmp ne i8 %x, 42 |
| %c2 = icmp ule i8 %x, %y |
| call void @use(i1 %c2) |
| %r = select i1 %c2, i1 true, i1 %c1 |
| ret i1 %r |
| } |
| |
| define i1 @or_ranges_overlap(i8 %x) { |
| ; CHECK-LABEL: @or_ranges_overlap( |
| ; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[X:%.*]], -5 |
| ; CHECK-NEXT: [[C7:%.*]] = icmp ult i8 [[TMP1]], 16 |
| ; CHECK-NEXT: ret i1 [[C7]] |
| ; |
| %c1 = icmp uge i8 %x, 5 |
| %c2 = icmp ule i8 %x, 10 |
| %c3 = and i1 %c1, %c2 |
| %c4 = icmp uge i8 %x, 10 |
| %c5 = icmp ule i8 %x, 20 |
| %c6 = and i1 %c4, %c5 |
| %c7 = or i1 %c3, %c6 |
| ret i1 %c7 |
| } |
| |
| define i1 @or_ranges_adjacent(i8 %x) { |
| ; CHECK-LABEL: @or_ranges_adjacent( |
| ; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[X:%.*]], -5 |
| ; CHECK-NEXT: [[C7:%.*]] = icmp ult i8 [[TMP1]], 16 |
| ; CHECK-NEXT: ret i1 [[C7]] |
| ; |
| %c1 = icmp uge i8 %x, 5 |
| %c2 = icmp ule i8 %x, 10 |
| %c3 = and i1 %c1, %c2 |
| %c4 = icmp uge i8 %x, 11 |
| %c5 = icmp ule i8 %x, 20 |
| %c6 = and i1 %c4, %c5 |
| %c7 = or i1 %c3, %c6 |
| ret i1 %c7 |
| } |
| |
| define i1 @or_ranges_separated(i8 %x) { |
| ; CHECK-LABEL: @or_ranges_separated( |
| ; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[X:%.*]], -5 |
| ; CHECK-NEXT: [[C3:%.*]] = icmp ult i8 [[TMP1]], 6 |
| ; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[X]], -12 |
| ; CHECK-NEXT: [[C6:%.*]] = icmp ult i8 [[TMP2]], 9 |
| ; CHECK-NEXT: [[C7:%.*]] = or i1 [[C3]], [[C6]] |
| ; CHECK-NEXT: ret i1 [[C7]] |
| ; |
| %c1 = icmp uge i8 %x, 5 |
| %c2 = icmp ule i8 %x, 10 |
| %c3 = and i1 %c1, %c2 |
| %c4 = icmp uge i8 %x, 12 |
| %c5 = icmp ule i8 %x, 20 |
| %c6 = and i1 %c4, %c5 |
| %c7 = or i1 %c3, %c6 |
| ret i1 %c7 |
| } |
| |
| define i1 @or_ranges_single_elem_right(i8 %x) { |
| ; CHECK-LABEL: @or_ranges_single_elem_right( |
| ; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[X:%.*]], -5 |
| ; CHECK-NEXT: [[C6:%.*]] = icmp ult i8 [[TMP1]], 7 |
| ; CHECK-NEXT: ret i1 [[C6]] |
| ; |
| %c1 = icmp uge i8 %x, 5 |
| %c2 = icmp ule i8 %x, 10 |
| %c3 = and i1 %c1, %c2 |
| %c4 = icmp eq i8 %x, 11 |
| %c6 = or i1 %c3, %c4 |
| ret i1 %c6 |
| } |
| |
| define i1 @or_ranges_single_elem_left(i8 %x) { |
| ; CHECK-LABEL: @or_ranges_single_elem_left( |
| ; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[X:%.*]], -4 |
| ; CHECK-NEXT: [[C6:%.*]] = icmp ult i8 [[TMP1]], 7 |
| ; CHECK-NEXT: ret i1 [[C6]] |
| ; |
| %c1 = icmp uge i8 %x, 5 |
| %c2 = icmp ule i8 %x, 10 |
| %c3 = and i1 %c1, %c2 |
| %c4 = icmp eq i8 %x, 4 |
| %c6 = or i1 %c3, %c4 |
| ret i1 %c6 |
| } |
| |
| define i1 @and_ranges_overlap(i8 %x) { |
| ; CHECK-LABEL: @and_ranges_overlap( |
| ; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[X:%.*]], -7 |
| ; CHECK-NEXT: [[C7:%.*]] = icmp ult i8 [[TMP1]], 4 |
| ; CHECK-NEXT: ret i1 [[C7]] |
| ; |
| %c1 = icmp uge i8 %x, 5 |
| %c2 = icmp ule i8 %x, 10 |
| %c3 = and i1 %c1, %c2 |
| %c4 = icmp uge i8 %x, 7 |
| %c5 = icmp ule i8 %x, 20 |
| %c6 = and i1 %c4, %c5 |
| %c7 = and i1 %c3, %c6 |
| ret i1 %c7 |
| } |
| |
| define i1 @and_ranges_overlap_single(i8 %x) { |
| ; CHECK-LABEL: @and_ranges_overlap_single( |
| ; CHECK-NEXT: [[C7:%.*]] = icmp eq i8 [[X:%.*]], 10 |
| ; CHECK-NEXT: ret i1 [[C7]] |
| ; |
| %c1 = icmp uge i8 %x, 5 |
| %c2 = icmp ule i8 %x, 10 |
| %c3 = and i1 %c1, %c2 |
| %c4 = icmp uge i8 %x, 10 |
| %c5 = icmp ule i8 %x, 20 |
| %c6 = and i1 %c4, %c5 |
| %c7 = and i1 %c3, %c6 |
| ret i1 %c7 |
| } |
| |
| define i1 @and_ranges_no_overlap(i8 %x) { |
| ; CHECK-LABEL: @and_ranges_no_overlap( |
| ; CHECK-NEXT: ret i1 false |
| ; |
| %c1 = icmp uge i8 %x, 5 |
| %c2 = icmp ule i8 %x, 10 |
| %c3 = and i1 %c1, %c2 |
| %c4 = icmp uge i8 %x, 11 |
| %c5 = icmp ule i8 %x, 20 |
| %c6 = and i1 %c4, %c5 |
| %c7 = and i1 %c3, %c6 |
| ret i1 %c7 |
| } |
| |
| define i1 @and_ranges_signed_pred(i64 %x) { |
| ; CHECK-LABEL: @and_ranges_signed_pred( |
| ; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[X:%.*]], -9223372036854775681 |
| ; CHECK-NEXT: [[T5:%.*]] = icmp ult i64 [[TMP1]], -9223372036854775553 |
| ; CHECK-NEXT: ret i1 [[T5]] |
| ; |
| %t1 = add i64 %x, 127 |
| %t2 = icmp slt i64 %t1, 1024 |
| %t3 = add i64 %x, 128 |
| %t4 = icmp slt i64 %t3, 256 |
| %t5 = and i1 %t2, %t4 |
| ret i1 %t5 |
| } |
| |
| define i1 @and_two_ranges_to_mask_and_range(i8 %c) { |
| ; CHECK-LABEL: @and_two_ranges_to_mask_and_range( |
| ; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[C:%.*]], -33 |
| ; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[TMP1]], -91 |
| ; CHECK-NEXT: [[AND:%.*]] = icmp ult i8 [[TMP2]], -26 |
| ; CHECK-NEXT: ret i1 [[AND]] |
| ; |
| %c.off = add i8 %c, -97 |
| %cmp1 = icmp ugt i8 %c.off, 25 |
| %c.off2 = add i8 %c, -65 |
| %cmp2 = icmp ugt i8 %c.off2, 25 |
| %and = and i1 %cmp1, %cmp2 |
| ret i1 %and |
| } |
| |
| define i1 @and_two_ranges_to_mask_and_range_not_pow2_diff(i8 %c) { |
| ; CHECK-LABEL: @and_two_ranges_to_mask_and_range_not_pow2_diff( |
| ; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[C:%.*]], -123 |
| ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i8 [[TMP1]], -26 |
| ; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[C]], -90 |
| ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i8 [[TMP2]], -26 |
| ; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]] |
| ; CHECK-NEXT: ret i1 [[AND]] |
| ; |
| %c.off = add i8 %c, -97 |
| %cmp1 = icmp ugt i8 %c.off, 25 |
| %c.off2 = add i8 %c, -64 |
| %cmp2 = icmp ugt i8 %c.off2, 25 |
| %and = and i1 %cmp1, %cmp2 |
| ret i1 %and |
| } |
| |
| define i1 @and_two_ranges_to_mask_and_range_different_sizes(i8 %c) { |
| ; CHECK-LABEL: @and_two_ranges_to_mask_and_range_different_sizes( |
| ; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[C:%.*]], -123 |
| ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i8 [[TMP1]], -26 |
| ; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[C]], -90 |
| ; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i8 [[TMP2]], -25 |
| ; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]] |
| ; CHECK-NEXT: ret i1 [[AND]] |
| ; |
| %c.off = add i8 %c, -97 |
| %cmp1 = icmp ugt i8 %c.off, 25 |
| %c.off2 = add i8 %c, -65 |
| %cmp2 = icmp ugt i8 %c.off2, 24 |
| %and = and i1 %cmp1, %cmp2 |
| ret i1 %and |
| } |
| |
| define i1 @and_two_ranges_to_mask_and_range_no_add_on_one_range(i16 %x) { |
| ; CHECK-LABEL: @and_two_ranges_to_mask_and_range_no_add_on_one_range( |
| ; CHECK-NEXT: [[TMP1:%.*]] = and i16 [[X:%.*]], -20 |
| ; CHECK-NEXT: [[AND:%.*]] = icmp ugt i16 [[TMP1]], 11 |
| ; CHECK-NEXT: ret i1 [[AND]] |
| ; |
| %cmp1 = icmp uge i16 %x, 12 |
| %cmp2 = icmp ult i16 %x, 16 |
| %cmp3 = icmp uge i16 %x, 28 |
| %or = or i1 %cmp2, %cmp3 |
| %and = and i1 %cmp1, %or |
| ret i1 %and |
| } |
| |
| ; This tests an "is_alpha" style check for the combination of logical or |
| ; and nowrap flags on the adds. In this case, the logical or will not be |
| ; converted into a bitwise or. |
| define i1 @is_ascii_alphabetic(i32 %char) { |
| ; CHECK-LABEL: @is_ascii_alphabetic( |
| ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[CHAR:%.*]], -33 |
| ; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], -65 |
| ; CHECK-NEXT: [[LOGICAL:%.*]] = icmp ult i32 [[TMP2]], 26 |
| ; CHECK-NEXT: ret i1 [[LOGICAL]] |
| ; |
| %add1 = add nsw i32 %char, -65 |
| %cmp1 = icmp ult i32 %add1, 26 |
| %add2 = add nsw i32 %char, -97 |
| %cmp2 = icmp ult i32 %add2, 26 |
| %logical = select i1 %cmp1, i1 true, i1 %cmp2 |
| ret i1 %logical |
| } |
| |
| define i1 @is_ascii_alphabetic_inverted(i32 %char) { |
| ; CHECK-LABEL: @is_ascii_alphabetic_inverted( |
| ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[CHAR:%.*]], -33 |
| ; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], -91 |
| ; CHECK-NEXT: [[LOGICAL:%.*]] = icmp ult i32 [[TMP2]], -26 |
| ; CHECK-NEXT: ret i1 [[LOGICAL]] |
| ; |
| %add1 = add nsw i32 %char, -91 |
| %cmp1 = icmp ult i32 %add1, -26 |
| %add2 = add nsw i32 %char, -123 |
| %cmp2 = icmp ult i32 %add2, -26 |
| %logical = select i1 %cmp1, i1 %cmp2, i1 false |
| ret i1 %logical |
| } |
| |
| define i1 @bitwise_and_bitwise_and_icmps(i8 %x, i8 %y, i8 %z) { |
| ; CHECK-LABEL: @bitwise_and_bitwise_and_icmps( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42 |
| ; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]] |
| ; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1 |
| ; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X:%.*]] |
| ; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8 [[TMP2]], [[TMP1]] |
| ; CHECK-NEXT: [[AND2:%.*]] = and i1 [[C1]], [[TMP3]] |
| ; CHECK-NEXT: ret i1 [[AND2]] |
| ; |
| %c1 = icmp eq i8 %y, 42 |
| %x.m1 = and i8 %x, 1 |
| %z.shift = shl i8 1, %z |
| %x.m2 = and i8 %x, %z.shift |
| %c2 = icmp ne i8 %x.m1, 0 |
| %c3 = icmp ne i8 %x.m2, 0 |
| %and1 = and i1 %c1, %c2 |
| %and2 = and i1 %and1, %c3 |
| ret i1 %and2 |
| } |
| |
| define i1 @bitwise_and_bitwise_and_icmps_comm1(i8 %x, i8 %y, i8 %z) { |
| ; CHECK-LABEL: @bitwise_and_bitwise_and_icmps_comm1( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42 |
| ; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]] |
| ; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1 |
| ; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X:%.*]] |
| ; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8 [[TMP2]], [[TMP1]] |
| ; CHECK-NEXT: [[AND2:%.*]] = and i1 [[C1]], [[TMP3]] |
| ; CHECK-NEXT: ret i1 [[AND2]] |
| ; |
| %c1 = icmp eq i8 %y, 42 |
| %x.m1 = and i8 %x, 1 |
| %z.shift = shl i8 1, %z |
| %x.m2 = and i8 %x, %z.shift |
| %c2 = icmp ne i8 %x.m1, 0 |
| %c3 = icmp ne i8 %x.m2, 0 |
| %and1 = and i1 %c1, %c2 |
| %and2 = and i1 %c3, %and1 |
| ret i1 %and2 |
| } |
| |
| define i1 @bitwise_and_bitwise_and_icmps_comm2(i8 %x, i8 %y, i8 %z) { |
| ; CHECK-LABEL: @bitwise_and_bitwise_and_icmps_comm2( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42 |
| ; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]] |
| ; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1 |
| ; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X:%.*]] |
| ; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8 [[TMP2]], [[TMP1]] |
| ; CHECK-NEXT: [[AND2:%.*]] = and i1 [[TMP3]], [[C1]] |
| ; CHECK-NEXT: ret i1 [[AND2]] |
| ; |
| %c1 = icmp eq i8 %y, 42 |
| %x.m1 = and i8 %x, 1 |
| %z.shift = shl i8 1, %z |
| %x.m2 = and i8 %x, %z.shift |
| %c2 = icmp ne i8 %x.m1, 0 |
| %c3 = icmp ne i8 %x.m2, 0 |
| %and1 = and i1 %c2, %c1 |
| %and2 = and i1 %and1, %c3 |
| ret i1 %and2 |
| } |
| |
| define i1 @bitwise_and_bitwise_and_icmps_comm3(i8 %x, i8 %y, i8 %z) { |
| ; CHECK-LABEL: @bitwise_and_bitwise_and_icmps_comm3( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42 |
| ; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]] |
| ; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1 |
| ; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X:%.*]] |
| ; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8 [[TMP2]], [[TMP1]] |
| ; CHECK-NEXT: [[AND2:%.*]] = and i1 [[TMP3]], [[C1]] |
| ; CHECK-NEXT: ret i1 [[AND2]] |
| ; |
| %c1 = icmp eq i8 %y, 42 |
| %x.m1 = and i8 %x, 1 |
| %z.shift = shl i8 1, %z |
| %x.m2 = and i8 %x, %z.shift |
| %c2 = icmp ne i8 %x.m1, 0 |
| %c3 = icmp ne i8 %x.m2, 0 |
| %and1 = and i1 %c2, %c1 |
| %and2 = and i1 %c3, %and1 |
| ret i1 %and2 |
| } |
| |
| define i1 @bitwise_and_logical_and_icmps(i8 %x, i8 %y, i8 %z) { |
| ; CHECK-LABEL: @bitwise_and_logical_and_icmps( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42 |
| ; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]] |
| ; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1 |
| ; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X:%.*]] |
| ; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8 [[TMP2]], [[TMP1]] |
| ; CHECK-NEXT: [[AND2:%.*]] = select i1 [[C1]], i1 [[TMP3]], i1 false |
| ; CHECK-NEXT: ret i1 [[AND2]] |
| ; |
| %c1 = icmp eq i8 %y, 42 |
| %x.m1 = and i8 %x, 1 |
| %z.shift = shl i8 1, %z |
| %x.m2 = and i8 %x, %z.shift |
| %c2 = icmp ne i8 %x.m1, 0 |
| %c3 = icmp ne i8 %x.m2, 0 |
| %and1 = select i1 %c1, i1 %c2, i1 false |
| %and2 = and i1 %and1, %c3 |
| ret i1 %and2 |
| } |
| |
| define i1 @bitwise_and_logical_and_icmps_comm1(i8 %x, i8 %y, i8 %z) { |
| ; CHECK-LABEL: @bitwise_and_logical_and_icmps_comm1( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42 |
| ; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]] |
| ; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1 |
| ; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X:%.*]] |
| ; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8 [[TMP2]], [[TMP1]] |
| ; CHECK-NEXT: [[AND2:%.*]] = select i1 [[C1]], i1 [[TMP3]], i1 false |
| ; CHECK-NEXT: ret i1 [[AND2]] |
| ; |
| %c1 = icmp eq i8 %y, 42 |
| %x.m1 = and i8 %x, 1 |
| %z.shift = shl i8 1, %z |
| %x.m2 = and i8 %x, %z.shift |
| %c2 = icmp ne i8 %x.m1, 0 |
| %c3 = icmp ne i8 %x.m2, 0 |
| %and1 = select i1 %c1, i1 %c2, i1 false |
| %and2 = and i1 %c3, %and1 |
| ret i1 %and2 |
| } |
| |
| define i1 @bitwise_and_logical_and_icmps_comm2(i8 %x, i8 %y, i8 %z) { |
| ; CHECK-LABEL: @bitwise_and_logical_and_icmps_comm2( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42 |
| ; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]] |
| ; CHECK-NEXT: [[TMP1:%.*]] = freeze i8 [[Z_SHIFT]] |
| ; CHECK-NEXT: [[TMP2:%.*]] = or i8 [[TMP1]], 1 |
| ; CHECK-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], [[X:%.*]] |
| ; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i8 [[TMP3]], [[TMP2]] |
| ; CHECK-NEXT: [[AND2:%.*]] = select i1 [[TMP4]], i1 [[C1]], i1 false |
| ; CHECK-NEXT: ret i1 [[AND2]] |
| ; |
| %c1 = icmp eq i8 %y, 42 |
| %x.m1 = and i8 %x, 1 |
| %z.shift = shl i8 1, %z |
| %x.m2 = and i8 %x, %z.shift |
| %c2 = icmp ne i8 %x.m1, 0 |
| %c3 = icmp ne i8 %x.m2, 0 |
| %and1 = select i1 %c2, i1 %c1, i1 false |
| %and2 = and i1 %and1, %c3 |
| ret i1 %and2 |
| } |
| |
| define i1 @bitwise_and_logical_and_icmps_comm3(i8 %x, i8 %y, i8 %z) { |
| ; CHECK-LABEL: @bitwise_and_logical_and_icmps_comm3( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42 |
| ; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]] |
| ; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1 |
| ; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X:%.*]] |
| ; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8 [[TMP2]], [[TMP1]] |
| ; CHECK-NEXT: [[AND2:%.*]] = select i1 [[TMP3]], i1 [[C1]], i1 false |
| ; CHECK-NEXT: ret i1 [[AND2]] |
| ; |
| %c1 = icmp eq i8 %y, 42 |
| %x.m1 = and i8 %x, 1 |
| %z.shift = shl i8 1, %z |
| %x.m2 = and i8 %x, %z.shift |
| %c2 = icmp ne i8 %x.m1, 0 |
| %c3 = icmp ne i8 %x.m2, 0 |
| %and1 = select i1 %c2, i1 %c1, i1 false |
| %and2 = and i1 %c3, %and1 |
| ret i1 %and2 |
| } |
| |
| define i1 @logical_and_bitwise_and_icmps(i8 %x, i8 %y, i8 %z) { |
| ; CHECK-LABEL: @logical_and_bitwise_and_icmps( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42 |
| ; CHECK-NEXT: [[X_M1:%.*]] = and i8 [[X:%.*]], 1 |
| ; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]] |
| ; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[Z_SHIFT]], [[X]] |
| ; CHECK-NEXT: [[C2:%.*]] = icmp ne i8 [[X_M1]], 0 |
| ; CHECK-NEXT: [[C3:%.*]] = icmp ne i8 [[X_M2]], 0 |
| ; CHECK-NEXT: [[AND1:%.*]] = and i1 [[C1]], [[C2]] |
| ; CHECK-NEXT: [[AND2:%.*]] = select i1 [[AND1]], i1 [[C3]], i1 false |
| ; CHECK-NEXT: ret i1 [[AND2]] |
| ; |
| %c1 = icmp eq i8 %y, 42 |
| %x.m1 = and i8 %x, 1 |
| %z.shift = shl i8 1, %z |
| %x.m2 = and i8 %x, %z.shift |
| %c2 = icmp ne i8 %x.m1, 0 |
| %c3 = icmp ne i8 %x.m2, 0 |
| %and1 = and i1 %c1, %c2 |
| %and2 = select i1 %and1, i1 %c3, i1 false |
| ret i1 %and2 |
| } |
| |
| define i1 @logical_and_bitwise_and_icmps_comm1(i8 %x, i8 %y, i8 %z) { |
| ; CHECK-LABEL: @logical_and_bitwise_and_icmps_comm1( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42 |
| ; CHECK-NEXT: [[X_M1:%.*]] = and i8 [[X:%.*]], 1 |
| ; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]] |
| ; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[Z_SHIFT]], [[X]] |
| ; CHECK-NEXT: [[C2:%.*]] = icmp ne i8 [[X_M1]], 0 |
| ; CHECK-NEXT: [[C3:%.*]] = icmp ne i8 [[X_M2]], 0 |
| ; CHECK-NEXT: [[AND1:%.*]] = and i1 [[C1]], [[C2]] |
| ; CHECK-NEXT: [[AND2:%.*]] = select i1 [[C3]], i1 [[AND1]], i1 false |
| ; CHECK-NEXT: ret i1 [[AND2]] |
| ; |
| %c1 = icmp eq i8 %y, 42 |
| %x.m1 = and i8 %x, 1 |
| %z.shift = shl i8 1, %z |
| %x.m2 = and i8 %x, %z.shift |
| %c2 = icmp ne i8 %x.m1, 0 |
| %c3 = icmp ne i8 %x.m2, 0 |
| %and1 = and i1 %c1, %c2 |
| %and2 = select i1 %c3, i1 %and1, i1 false |
| ret i1 %and2 |
| } |
| |
| define i1 @logical_and_bitwise_and_icmps_comm2(i8 %x, i8 %y, i8 %z) { |
| ; CHECK-LABEL: @logical_and_bitwise_and_icmps_comm2( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42 |
| ; CHECK-NEXT: [[X_M1:%.*]] = and i8 [[X:%.*]], 1 |
| ; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]] |
| ; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[Z_SHIFT]], [[X]] |
| ; CHECK-NEXT: [[C2:%.*]] = icmp ne i8 [[X_M1]], 0 |
| ; CHECK-NEXT: [[C3:%.*]] = icmp ne i8 [[X_M2]], 0 |
| ; CHECK-NEXT: [[AND1:%.*]] = and i1 [[C2]], [[C1]] |
| ; CHECK-NEXT: [[AND2:%.*]] = select i1 [[AND1]], i1 [[C3]], i1 false |
| ; CHECK-NEXT: ret i1 [[AND2]] |
| ; |
| %c1 = icmp eq i8 %y, 42 |
| %x.m1 = and i8 %x, 1 |
| %z.shift = shl i8 1, %z |
| %x.m2 = and i8 %x, %z.shift |
| %c2 = icmp ne i8 %x.m1, 0 |
| %c3 = icmp ne i8 %x.m2, 0 |
| %and1 = and i1 %c2, %c1 |
| %and2 = select i1 %and1, i1 %c3, i1 false |
| ret i1 %and2 |
| } |
| |
| define i1 @logical_and_bitwise_and_icmps_comm3(i8 %x, i8 %y, i8 %z) { |
| ; CHECK-LABEL: @logical_and_bitwise_and_icmps_comm3( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42 |
| ; CHECK-NEXT: [[X_M1:%.*]] = and i8 [[X:%.*]], 1 |
| ; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]] |
| ; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[Z_SHIFT]], [[X]] |
| ; CHECK-NEXT: [[C2:%.*]] = icmp ne i8 [[X_M1]], 0 |
| ; CHECK-NEXT: [[C3:%.*]] = icmp ne i8 [[X_M2]], 0 |
| ; CHECK-NEXT: [[AND1:%.*]] = and i1 [[C2]], [[C1]] |
| ; CHECK-NEXT: [[AND2:%.*]] = select i1 [[C3]], i1 [[AND1]], i1 false |
| ; CHECK-NEXT: ret i1 [[AND2]] |
| ; |
| %c1 = icmp eq i8 %y, 42 |
| %x.m1 = and i8 %x, 1 |
| %z.shift = shl i8 1, %z |
| %x.m2 = and i8 %x, %z.shift |
| %c2 = icmp ne i8 %x.m1, 0 |
| %c3 = icmp ne i8 %x.m2, 0 |
| %and1 = and i1 %c2, %c1 |
| %and2 = select i1 %c3, i1 %and1, i1 false |
| ret i1 %and2 |
| } |
| |
| define i1 @logical_and_logical_and_icmps(i8 %x, i8 %y, i8 %z) { |
| ; CHECK-LABEL: @logical_and_logical_and_icmps( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42 |
| ; CHECK-NEXT: [[X_M1:%.*]] = and i8 [[X:%.*]], 1 |
| ; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]] |
| ; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[Z_SHIFT]], [[X]] |
| ; CHECK-NEXT: [[C2:%.*]] = icmp ne i8 [[X_M1]], 0 |
| ; CHECK-NEXT: [[C3:%.*]] = icmp ne i8 [[X_M2]], 0 |
| ; CHECK-NEXT: [[AND1:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false |
| ; CHECK-NEXT: [[AND2:%.*]] = select i1 [[AND1]], i1 [[C3]], i1 false |
| ; CHECK-NEXT: ret i1 [[AND2]] |
| ; |
| %c1 = icmp eq i8 %y, 42 |
| %x.m1 = and i8 %x, 1 |
| %z.shift = shl i8 1, %z |
| %x.m2 = and i8 %x, %z.shift |
| %c2 = icmp ne i8 %x.m1, 0 |
| %c3 = icmp ne i8 %x.m2, 0 |
| %and1 = select i1 %c1, i1 %c2, i1 false |
| %and2 = select i1 %and1, i1 %c3, i1 false |
| ret i1 %and2 |
| } |
| |
| define i1 @logical_and_logical_and_icmps_comm1(i8 %x, i8 %y, i8 %z) { |
| ; CHECK-LABEL: @logical_and_logical_and_icmps_comm1( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42 |
| ; CHECK-NEXT: [[X_M1:%.*]] = and i8 [[X:%.*]], 1 |
| ; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]] |
| ; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[Z_SHIFT]], [[X]] |
| ; CHECK-NEXT: [[C2:%.*]] = icmp ne i8 [[X_M1]], 0 |
| ; CHECK-NEXT: [[C3:%.*]] = icmp ne i8 [[X_M2]], 0 |
| ; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[C3]], i1 [[C1]], i1 false |
| ; CHECK-NEXT: [[AND2:%.*]] = select i1 [[TMP1]], i1 [[C2]], i1 false |
| ; CHECK-NEXT: ret i1 [[AND2]] |
| ; |
| %c1 = icmp eq i8 %y, 42 |
| %x.m1 = and i8 %x, 1 |
| %z.shift = shl i8 1, %z |
| %x.m2 = and i8 %x, %z.shift |
| %c2 = icmp ne i8 %x.m1, 0 |
| %c3 = icmp ne i8 %x.m2, 0 |
| %and1 = select i1 %c1, i1 %c2, i1 false |
| %and2 = select i1 %c3, i1 %and1, i1 false |
| ret i1 %and2 |
| } |
| |
| define i1 @logical_and_logical_and_icmps_comm2(i8 %x, i8 %y, i8 %z) { |
| ; CHECK-LABEL: @logical_and_logical_and_icmps_comm2( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42 |
| ; CHECK-NEXT: [[X_M1:%.*]] = and i8 [[X:%.*]], 1 |
| ; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]] |
| ; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[Z_SHIFT]], [[X]] |
| ; CHECK-NEXT: [[C2:%.*]] = icmp ne i8 [[X_M1]], 0 |
| ; CHECK-NEXT: [[C3:%.*]] = icmp ne i8 [[X_M2]], 0 |
| ; CHECK-NEXT: [[AND1:%.*]] = select i1 [[C2]], i1 [[C1]], i1 false |
| ; CHECK-NEXT: [[AND2:%.*]] = select i1 [[AND1]], i1 [[C3]], i1 false |
| ; CHECK-NEXT: ret i1 [[AND2]] |
| ; |
| %c1 = icmp eq i8 %y, 42 |
| %x.m1 = and i8 %x, 1 |
| %z.shift = shl i8 1, %z |
| %x.m2 = and i8 %x, %z.shift |
| %c2 = icmp ne i8 %x.m1, 0 |
| %c3 = icmp ne i8 %x.m2, 0 |
| %and1 = select i1 %c2, i1 %c1, i1 false |
| %and2 = select i1 %and1, i1 %c3, i1 false |
| ret i1 %and2 |
| } |
| |
| define i1 @logical_and_logical_and_icmps_comm3(i8 %x, i8 %y, i8 %z) { |
| ; CHECK-LABEL: @logical_and_logical_and_icmps_comm3( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42 |
| ; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]] |
| ; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1 |
| ; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X:%.*]] |
| ; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8 [[TMP2]], [[TMP1]] |
| ; CHECK-NEXT: [[AND2:%.*]] = select i1 [[TMP3]], i1 [[C1]], i1 false |
| ; CHECK-NEXT: ret i1 [[AND2]] |
| ; |
| %c1 = icmp eq i8 %y, 42 |
| %x.m1 = and i8 %x, 1 |
| %z.shift = shl i8 1, %z |
| %x.m2 = and i8 %x, %z.shift |
| %c2 = icmp ne i8 %x.m1, 0 |
| %c3 = icmp ne i8 %x.m2, 0 |
| %and1 = select i1 %c2, i1 %c1, i1 false |
| %and2 = select i1 %c3, i1 %and1, i1 false |
| ret i1 %and2 |
| } |
| |
| define i1 @bitwise_or_bitwise_or_icmps(i8 %x, i8 %y, i8 %z) { |
| ; CHECK-LABEL: @bitwise_or_bitwise_or_icmps( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42 |
| ; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]] |
| ; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1 |
| ; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X:%.*]] |
| ; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i8 [[TMP2]], [[TMP1]] |
| ; CHECK-NEXT: [[OR2:%.*]] = or i1 [[C1]], [[TMP3]] |
| ; CHECK-NEXT: ret i1 [[OR2]] |
| ; |
| %c1 = icmp eq i8 %y, 42 |
| %x.m1 = and i8 %x, 1 |
| %z.shift = shl i8 1, %z |
| %x.m2 = and i8 %x, %z.shift |
| %c2 = icmp eq i8 %x.m1, 0 |
| %c3 = icmp eq i8 %x.m2, 0 |
| %or1 = or i1 %c1, %c2 |
| %or2 = or i1 %or1, %c3 |
| ret i1 %or2 |
| } |
| |
| define i1 @bitwise_or_bitwise_or_icmps_comm1(i8 %x, i8 %y, i8 %z) { |
| ; CHECK-LABEL: @bitwise_or_bitwise_or_icmps_comm1( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42 |
| ; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]] |
| ; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1 |
| ; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X:%.*]] |
| ; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i8 [[TMP2]], [[TMP1]] |
| ; CHECK-NEXT: [[OR2:%.*]] = or i1 [[C1]], [[TMP3]] |
| ; CHECK-NEXT: ret i1 [[OR2]] |
| ; |
| %c1 = icmp eq i8 %y, 42 |
| %x.m1 = and i8 %x, 1 |
| %z.shift = shl i8 1, %z |
| %x.m2 = and i8 %x, %z.shift |
| %c2 = icmp eq i8 %x.m1, 0 |
| %c3 = icmp eq i8 %x.m2, 0 |
| %or1 = or i1 %c1, %c2 |
| %or2 = or i1 %c3, %or1 |
| ret i1 %or2 |
| } |
| |
| define i1 @bitwise_or_bitwise_or_icmps_comm2(i8 %x, i8 %y, i8 %z) { |
| ; CHECK-LABEL: @bitwise_or_bitwise_or_icmps_comm2( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42 |
| ; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]] |
| ; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1 |
| ; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X:%.*]] |
| ; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i8 [[TMP2]], [[TMP1]] |
| ; CHECK-NEXT: [[OR2:%.*]] = or i1 [[TMP3]], [[C1]] |
| ; CHECK-NEXT: ret i1 [[OR2]] |
| ; |
| %c1 = icmp eq i8 %y, 42 |
| %x.m1 = and i8 %x, 1 |
| %z.shift = shl i8 1, %z |
| %x.m2 = and i8 %x, %z.shift |
| %c2 = icmp eq i8 %x.m1, 0 |
| %c3 = icmp eq i8 %x.m2, 0 |
| %or1 = or i1 %c2, %c1 |
| %or2 = or i1 %or1, %c3 |
| ret i1 %or2 |
| } |
| |
| define i1 @bitwise_or_bitwise_or_icmps_comm3(i8 %x, i8 %y, i8 %z) { |
| ; CHECK-LABEL: @bitwise_or_bitwise_or_icmps_comm3( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42 |
| ; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]] |
| ; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1 |
| ; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X:%.*]] |
| ; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i8 [[TMP2]], [[TMP1]] |
| ; CHECK-NEXT: [[OR2:%.*]] = or i1 [[TMP3]], [[C1]] |
| ; CHECK-NEXT: ret i1 [[OR2]] |
| ; |
| %c1 = icmp eq i8 %y, 42 |
| %x.m1 = and i8 %x, 1 |
| %z.shift = shl i8 1, %z |
| %x.m2 = and i8 %x, %z.shift |
| %c2 = icmp eq i8 %x.m1, 0 |
| %c3 = icmp eq i8 %x.m2, 0 |
| %or1 = or i1 %c2, %c1 |
| %or2 = or i1 %c3, %or1 |
| ret i1 %or2 |
| } |
| |
| define i1 @bitwise_or_logical_or_icmps(i8 %x, i8 %y, i8 %z) { |
| ; CHECK-LABEL: @bitwise_or_logical_or_icmps( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42 |
| ; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]] |
| ; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1 |
| ; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X:%.*]] |
| ; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i8 [[TMP2]], [[TMP1]] |
| ; CHECK-NEXT: [[OR2:%.*]] = select i1 [[C1]], i1 true, i1 [[TMP3]] |
| ; CHECK-NEXT: ret i1 [[OR2]] |
| ; |
| %c1 = icmp eq i8 %y, 42 |
| %x.m1 = and i8 %x, 1 |
| %z.shift = shl i8 1, %z |
| %x.m2 = and i8 %x, %z.shift |
| %c2 = icmp eq i8 %x.m1, 0 |
| %c3 = icmp eq i8 %x.m2, 0 |
| %or1 = select i1 %c1, i1 true, i1 %c2 |
| %or2 = or i1 %or1, %c3 |
| ret i1 %or2 |
| } |
| |
| define i1 @bitwise_or_logical_or_icmps_comm1(i8 %x, i8 %y, i8 %z) { |
| ; CHECK-LABEL: @bitwise_or_logical_or_icmps_comm1( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42 |
| ; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]] |
| ; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1 |
| ; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X:%.*]] |
| ; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i8 [[TMP2]], [[TMP1]] |
| ; CHECK-NEXT: [[OR2:%.*]] = select i1 [[C1]], i1 true, i1 [[TMP3]] |
| ; CHECK-NEXT: ret i1 [[OR2]] |
| ; |
| %c1 = icmp eq i8 %y, 42 |
| %x.m1 = and i8 %x, 1 |
| %z.shift = shl i8 1, %z |
| %x.m2 = and i8 %x, %z.shift |
| %c2 = icmp eq i8 %x.m1, 0 |
| %c3 = icmp eq i8 %x.m2, 0 |
| %or1 = select i1 %c1, i1 true, i1 %c2 |
| %or2 = or i1 %c3, %or1 |
| ret i1 %or2 |
| } |
| |
| define i1 @bitwise_or_logical_or_icmps_comm2(i8 %x, i8 %y, i8 %z) { |
| ; CHECK-LABEL: @bitwise_or_logical_or_icmps_comm2( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42 |
| ; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]] |
| ; CHECK-NEXT: [[TMP1:%.*]] = freeze i8 [[Z_SHIFT]] |
| ; CHECK-NEXT: [[TMP2:%.*]] = or i8 [[TMP1]], 1 |
| ; CHECK-NEXT: [[TMP3:%.*]] = and i8 [[TMP2]], [[X:%.*]] |
| ; CHECK-NEXT: [[TMP4:%.*]] = icmp ne i8 [[TMP3]], [[TMP2]] |
| ; CHECK-NEXT: [[OR2:%.*]] = select i1 [[TMP4]], i1 true, i1 [[C1]] |
| ; CHECK-NEXT: ret i1 [[OR2]] |
| ; |
| %c1 = icmp eq i8 %y, 42 |
| %x.m1 = and i8 %x, 1 |
| %z.shift = shl i8 1, %z |
| %x.m2 = and i8 %x, %z.shift |
| %c2 = icmp eq i8 %x.m1, 0 |
| %c3 = icmp eq i8 %x.m2, 0 |
| %or1 = select i1 %c2, i1 true, i1 %c1 |
| %or2 = or i1 %or1, %c3 |
| ret i1 %or2 |
| } |
| |
| define i1 @bitwise_or_logical_or_icmps_comm3(i8 %x, i8 %y, i8 %z) { |
| ; CHECK-LABEL: @bitwise_or_logical_or_icmps_comm3( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42 |
| ; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]] |
| ; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1 |
| ; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X:%.*]] |
| ; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i8 [[TMP2]], [[TMP1]] |
| ; CHECK-NEXT: [[OR2:%.*]] = select i1 [[TMP3]], i1 true, i1 [[C1]] |
| ; CHECK-NEXT: ret i1 [[OR2]] |
| ; |
| %c1 = icmp eq i8 %y, 42 |
| %x.m1 = and i8 %x, 1 |
| %z.shift = shl i8 1, %z |
| %x.m2 = and i8 %x, %z.shift |
| %c2 = icmp eq i8 %x.m1, 0 |
| %c3 = icmp eq i8 %x.m2, 0 |
| %or1 = select i1 %c2, i1 true, i1 %c1 |
| %or2 = or i1 %c3, %or1 |
| ret i1 %or2 |
| } |
| |
| define i1 @logical_or_bitwise_or_icmps(i8 %x, i8 %y, i8 %z) { |
| ; CHECK-LABEL: @logical_or_bitwise_or_icmps( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42 |
| ; CHECK-NEXT: [[X_M1:%.*]] = and i8 [[X:%.*]], 1 |
| ; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]] |
| ; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[Z_SHIFT]], [[X]] |
| ; CHECK-NEXT: [[C2:%.*]] = icmp eq i8 [[X_M1]], 0 |
| ; CHECK-NEXT: [[C3:%.*]] = icmp eq i8 [[X_M2]], 0 |
| ; CHECK-NEXT: [[OR1:%.*]] = or i1 [[C1]], [[C2]] |
| ; CHECK-NEXT: [[OR2:%.*]] = select i1 [[OR1]], i1 true, i1 [[C3]] |
| ; CHECK-NEXT: ret i1 [[OR2]] |
| ; |
| %c1 = icmp eq i8 %y, 42 |
| %x.m1 = and i8 %x, 1 |
| %z.shift = shl i8 1, %z |
| %x.m2 = and i8 %x, %z.shift |
| %c2 = icmp eq i8 %x.m1, 0 |
| %c3 = icmp eq i8 %x.m2, 0 |
| %or1 = or i1 %c1, %c2 |
| %or2 = select i1 %or1, i1 true, i1 %c3 |
| ret i1 %or2 |
| } |
| |
| define i1 @logical_or_bitwise_or_icmps_comm1(i8 %x, i8 %y, i8 %z) { |
| ; CHECK-LABEL: @logical_or_bitwise_or_icmps_comm1( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42 |
| ; CHECK-NEXT: [[X_M1:%.*]] = and i8 [[X:%.*]], 1 |
| ; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]] |
| ; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[Z_SHIFT]], [[X]] |
| ; CHECK-NEXT: [[C2:%.*]] = icmp eq i8 [[X_M1]], 0 |
| ; CHECK-NEXT: [[C3:%.*]] = icmp eq i8 [[X_M2]], 0 |
| ; CHECK-NEXT: [[OR1:%.*]] = or i1 [[C1]], [[C2]] |
| ; CHECK-NEXT: [[OR2:%.*]] = select i1 [[C3]], i1 true, i1 [[OR1]] |
| ; CHECK-NEXT: ret i1 [[OR2]] |
| ; |
| %c1 = icmp eq i8 %y, 42 |
| %x.m1 = and i8 %x, 1 |
| %z.shift = shl i8 1, %z |
| %x.m2 = and i8 %x, %z.shift |
| %c2 = icmp eq i8 %x.m1, 0 |
| %c3 = icmp eq i8 %x.m2, 0 |
| %or1 = or i1 %c1, %c2 |
| %or2 = select i1 %c3, i1 true, i1 %or1 |
| ret i1 %or2 |
| } |
| |
| define i1 @logical_or_bitwise_or_icmps_comm2(i8 %x, i8 %y, i8 %z) { |
| ; CHECK-LABEL: @logical_or_bitwise_or_icmps_comm2( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42 |
| ; CHECK-NEXT: [[X_M1:%.*]] = and i8 [[X:%.*]], 1 |
| ; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]] |
| ; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[Z_SHIFT]], [[X]] |
| ; CHECK-NEXT: [[C2:%.*]] = icmp eq i8 [[X_M1]], 0 |
| ; CHECK-NEXT: [[C3:%.*]] = icmp eq i8 [[X_M2]], 0 |
| ; CHECK-NEXT: [[OR1:%.*]] = or i1 [[C2]], [[C1]] |
| ; CHECK-NEXT: [[OR2:%.*]] = select i1 [[OR1]], i1 true, i1 [[C3]] |
| ; CHECK-NEXT: ret i1 [[OR2]] |
| ; |
| %c1 = icmp eq i8 %y, 42 |
| %x.m1 = and i8 %x, 1 |
| %z.shift = shl i8 1, %z |
| %x.m2 = and i8 %x, %z.shift |
| %c2 = icmp eq i8 %x.m1, 0 |
| %c3 = icmp eq i8 %x.m2, 0 |
| %or1 = or i1 %c2, %c1 |
| %or2 = select i1 %or1, i1 true, i1 %c3 |
| ret i1 %or2 |
| } |
| |
| define i1 @logical_or_bitwise_or_icmps_comm3(i8 %x, i8 %y, i8 %z) { |
| ; CHECK-LABEL: @logical_or_bitwise_or_icmps_comm3( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42 |
| ; CHECK-NEXT: [[X_M1:%.*]] = and i8 [[X:%.*]], 1 |
| ; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]] |
| ; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[Z_SHIFT]], [[X]] |
| ; CHECK-NEXT: [[C2:%.*]] = icmp eq i8 [[X_M1]], 0 |
| ; CHECK-NEXT: [[C3:%.*]] = icmp eq i8 [[X_M2]], 0 |
| ; CHECK-NEXT: [[OR1:%.*]] = or i1 [[C2]], [[C1]] |
| ; CHECK-NEXT: [[OR2:%.*]] = select i1 [[C3]], i1 true, i1 [[OR1]] |
| ; CHECK-NEXT: ret i1 [[OR2]] |
| ; |
| %c1 = icmp eq i8 %y, 42 |
| %x.m1 = and i8 %x, 1 |
| %z.shift = shl i8 1, %z |
| %x.m2 = and i8 %x, %z.shift |
| %c2 = icmp eq i8 %x.m1, 0 |
| %c3 = icmp eq i8 %x.m2, 0 |
| %or1 = or i1 %c2, %c1 |
| %or2 = select i1 %c3, i1 true, i1 %or1 |
| ret i1 %or2 |
| } |
| |
| define i1 @logical_or_logical_or_icmps(i8 %x, i8 %y, i8 %z) { |
| ; CHECK-LABEL: @logical_or_logical_or_icmps( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42 |
| ; CHECK-NEXT: [[X_M1:%.*]] = and i8 [[X:%.*]], 1 |
| ; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]] |
| ; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[Z_SHIFT]], [[X]] |
| ; CHECK-NEXT: [[C2:%.*]] = icmp eq i8 [[X_M1]], 0 |
| ; CHECK-NEXT: [[C3:%.*]] = icmp eq i8 [[X_M2]], 0 |
| ; CHECK-NEXT: [[OR1:%.*]] = select i1 [[C1]], i1 true, i1 [[C2]] |
| ; CHECK-NEXT: [[OR2:%.*]] = select i1 [[OR1]], i1 true, i1 [[C3]] |
| ; CHECK-NEXT: ret i1 [[OR2]] |
| ; |
| %c1 = icmp eq i8 %y, 42 |
| %x.m1 = and i8 %x, 1 |
| %z.shift = shl i8 1, %z |
| %x.m2 = and i8 %x, %z.shift |
| %c2 = icmp eq i8 %x.m1, 0 |
| %c3 = icmp eq i8 %x.m2, 0 |
| %or1 = select i1 %c1, i1 true, i1 %c2 |
| %or2 = select i1 %or1, i1 true, i1 %c3 |
| ret i1 %or2 |
| } |
| |
| define i1 @logical_or_logical_or_icmps_comm1(i8 %x, i8 %y, i8 %z) { |
| ; CHECK-LABEL: @logical_or_logical_or_icmps_comm1( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42 |
| ; CHECK-NEXT: [[X_M1:%.*]] = and i8 [[X:%.*]], 1 |
| ; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]] |
| ; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[Z_SHIFT]], [[X]] |
| ; CHECK-NEXT: [[C2:%.*]] = icmp eq i8 [[X_M1]], 0 |
| ; CHECK-NEXT: [[C3:%.*]] = icmp eq i8 [[X_M2]], 0 |
| ; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[C3]], i1 true, i1 [[C1]] |
| ; CHECK-NEXT: [[OR2:%.*]] = select i1 [[TMP1]], i1 true, i1 [[C2]] |
| ; CHECK-NEXT: ret i1 [[OR2]] |
| ; |
| %c1 = icmp eq i8 %y, 42 |
| %x.m1 = and i8 %x, 1 |
| %z.shift = shl i8 1, %z |
| %x.m2 = and i8 %x, %z.shift |
| %c2 = icmp eq i8 %x.m1, 0 |
| %c3 = icmp eq i8 %x.m2, 0 |
| %or1 = select i1 %c1, i1 true, i1 %c2 |
| %or2 = select i1 %c3, i1 true, i1 %or1 |
| ret i1 %or2 |
| } |
| |
| define i1 @logical_or_logical_or_icmps_comm2(i8 %x, i8 %y, i8 %z) { |
| ; CHECK-LABEL: @logical_or_logical_or_icmps_comm2( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42 |
| ; CHECK-NEXT: [[X_M1:%.*]] = and i8 [[X:%.*]], 1 |
| ; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]] |
| ; CHECK-NEXT: [[X_M2:%.*]] = and i8 [[Z_SHIFT]], [[X]] |
| ; CHECK-NEXT: [[C2:%.*]] = icmp eq i8 [[X_M1]], 0 |
| ; CHECK-NEXT: [[C3:%.*]] = icmp eq i8 [[X_M2]], 0 |
| ; CHECK-NEXT: [[OR1:%.*]] = select i1 [[C2]], i1 true, i1 [[C1]] |
| ; CHECK-NEXT: [[OR2:%.*]] = select i1 [[OR1]], i1 true, i1 [[C3]] |
| ; CHECK-NEXT: ret i1 [[OR2]] |
| ; |
| %c1 = icmp eq i8 %y, 42 |
| %x.m1 = and i8 %x, 1 |
| %z.shift = shl i8 1, %z |
| %x.m2 = and i8 %x, %z.shift |
| %c2 = icmp eq i8 %x.m1, 0 |
| %c3 = icmp eq i8 %x.m2, 0 |
| %or1 = select i1 %c2, i1 true, i1 %c1 |
| %or2 = select i1 %or1, i1 true, i1 %c3 |
| ret i1 %or2 |
| } |
| |
| define i1 @logical_or_logical_or_icmps_comm3(i8 %x, i8 %y, i8 %z) { |
| ; CHECK-LABEL: @logical_or_logical_or_icmps_comm3( |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[Y:%.*]], 42 |
| ; CHECK-NEXT: [[Z_SHIFT:%.*]] = shl nuw i8 1, [[Z:%.*]] |
| ; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[Z_SHIFT]], 1 |
| ; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[TMP1]], [[X:%.*]] |
| ; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i8 [[TMP2]], [[TMP1]] |
| ; CHECK-NEXT: [[OR2:%.*]] = select i1 [[TMP3]], i1 true, i1 [[C1]] |
| ; CHECK-NEXT: ret i1 [[OR2]] |
| ; |
| %c1 = icmp eq i8 %y, 42 |
| %x.m1 = and i8 %x, 1 |
| %z.shift = shl i8 1, %z |
| %x.m2 = and i8 %x, %z.shift |
| %c2 = icmp eq i8 %x.m1, 0 |
| %c3 = icmp eq i8 %x.m2, 0 |
| %or1 = select i1 %c2, i1 true, i1 %c1 |
| %or2 = select i1 %c3, i1 true, i1 %or1 |
| ret i1 %or2 |
| } |
| |
| define i1 @bitwise_and_logical_and_masked_icmp_asymmetric(i1 %c, i32 %x) { |
| ; CHECK-LABEL: @bitwise_and_logical_and_masked_icmp_asymmetric( |
| ; CHECK-NEXT: [[X_M2:%.*]] = and i32 [[X:%.*]], 11 |
| ; CHECK-NEXT: [[C2:%.*]] = icmp eq i32 [[X_M2]], 11 |
| ; CHECK-NEXT: [[AND2:%.*]] = select i1 [[C2]], i1 [[C:%.*]], i1 false |
| ; CHECK-NEXT: ret i1 [[AND2]] |
| ; |
| %x.m1 = and i32 %x, 255 |
| %c1 = icmp ne i32 %x.m1, 0 |
| %and1 = select i1 %c1, i1 %c, i1 false |
| %x.m2 = and i32 %x, 11 |
| %c2 = icmp eq i32 %x.m2, 11 |
| %and2 = and i1 %and1, %c2 |
| ret i1 %and2 |
| } |
| |
| define i1 @bitwise_and_logical_and_masked_icmp_allzeros(i1 %c, i32 %x) { |
| ; CHECK-LABEL: @bitwise_and_logical_and_masked_icmp_allzeros( |
| ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 15 |
| ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0 |
| ; CHECK-NEXT: [[AND2:%.*]] = select i1 [[TMP2]], i1 [[C:%.*]], i1 false |
| ; CHECK-NEXT: ret i1 [[AND2]] |
| ; |
| %x.m1 = and i32 %x, 8 |
| %c1 = icmp eq i32 %x.m1, 0 |
| %and1 = select i1 %c1, i1 %c, i1 false |
| %x.m2 = and i32 %x, 7 |
| %c2 = icmp eq i32 %x.m2, 0 |
| %and2 = and i1 %and1, %c2 |
| ret i1 %and2 |
| } |
| |
| define i1 @bitwise_and_logical_and_masked_icmp_allzeros_poison1(i1 %c, i32 %x, i32 %y) { |
| ; CHECK-LABEL: @bitwise_and_logical_and_masked_icmp_allzeros_poison1( |
| ; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[Y:%.*]], 7 |
| ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[X:%.*]] |
| ; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 0 |
| ; CHECK-NEXT: [[AND2:%.*]] = select i1 [[TMP3]], i1 [[C:%.*]], i1 false |
| ; CHECK-NEXT: ret i1 [[AND2]] |
| ; |
| %x.m1 = and i32 %x, %y |
| %c1 = icmp eq i32 %x.m1, 0 |
| %and1 = select i1 %c1, i1 %c, i1 false |
| %x.m2 = and i32 %x, 7 |
| %c2 = icmp eq i32 %x.m2, 0 |
| %and2 = and i1 %and1, %c2 |
| ret i1 %and2 |
| } |
| |
| define i1 @bitwise_and_logical_and_masked_icmp_allzeros_poison2(i1 %c, i32 %x, i32 %y) { |
| ; CHECK-LABEL: @bitwise_and_logical_and_masked_icmp_allzeros_poison2( |
| ; CHECK-NEXT: [[X_M1:%.*]] = and i32 [[X:%.*]], 8 |
| ; CHECK-NEXT: [[C1:%.*]] = icmp eq i32 [[X_M1]], 0 |
| ; CHECK-NEXT: [[AND1:%.*]] = select i1 [[C1]], i1 [[C:%.*]], i1 false |
| ; CHECK-NEXT: [[X_M2:%.*]] = and i32 [[X]], [[Y:%.*]] |
| ; CHECK-NEXT: [[C2:%.*]] = icmp eq i32 [[X_M2]], 0 |
| ; CHECK-NEXT: [[AND2:%.*]] = and i1 [[AND1]], [[C2]] |
| ; CHECK-NEXT: ret i1 [[AND2]] |
| ; |
| %x.m1 = and i32 %x, 8 |
| %c1 = icmp eq i32 %x.m1, 0 |
| %and1 = select i1 %c1, i1 %c, i1 false |
| %x.m2 = and i32 %x, %y |
| %c2 = icmp eq i32 %x.m2, 0 |
| %and2 = and i1 %and1, %c2 |
| ret i1 %and2 |
| } |
| |
| define i1 @bitwise_and_logical_and_masked_icmp_allones(i1 %c, i32 %x) { |
| ; CHECK-LABEL: @bitwise_and_logical_and_masked_icmp_allones( |
| ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 15 |
| ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 15 |
| ; CHECK-NEXT: [[AND2:%.*]] = select i1 [[TMP2]], i1 [[C:%.*]], i1 false |
| ; CHECK-NEXT: ret i1 [[AND2]] |
| ; |
| %x.m1 = and i32 %x, 8 |
| %c1 = icmp eq i32 %x.m1, 8 |
| %and1 = select i1 %c1, i1 %c, i1 false |
| %x.m2 = and i32 %x, 7 |
| %c2 = icmp eq i32 %x.m2, 7 |
| %and2 = and i1 %and1, %c2 |
| ret i1 %and2 |
| } |
| |
| define i1 @bitwise_and_logical_and_masked_icmp_allones_poison1(i1 %c, i32 %x, i32 %y) { |
| ; CHECK-LABEL: @bitwise_and_logical_and_masked_icmp_allones_poison1( |
| ; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[Y:%.*]], 7 |
| ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[X:%.*]] |
| ; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], [[TMP1]] |
| ; CHECK-NEXT: [[AND2:%.*]] = select i1 [[TMP3]], i1 [[C:%.*]], i1 false |
| ; CHECK-NEXT: ret i1 [[AND2]] |
| ; |
| %x.m1 = and i32 %x, %y |
| %c1 = icmp eq i32 %x.m1, %y |
| %and1 = select i1 %c1, i1 %c, i1 false |
| %x.m2 = and i32 %x, 7 |
| %c2 = icmp eq i32 %x.m2, 7 |
| %and2 = and i1 %and1, %c2 |
| ret i1 %and2 |
| } |
| |
| define i1 @bitwise_and_logical_and_masked_icmp_allones_poison2(i1 %c, i32 %x, i32 %y) { |
| ; CHECK-LABEL: @bitwise_and_logical_and_masked_icmp_allones_poison2( |
| ; CHECK-NEXT: [[X_M1:%.*]] = and i32 [[X:%.*]], 8 |
| ; CHECK-NEXT: [[C1:%.*]] = icmp ne i32 [[X_M1]], 0 |
| ; CHECK-NEXT: [[AND1:%.*]] = select i1 [[C1]], i1 [[C:%.*]], i1 false |
| ; CHECK-NEXT: [[X_M2:%.*]] = and i32 [[X]], [[Y:%.*]] |
| ; CHECK-NEXT: [[C2:%.*]] = icmp eq i32 [[X_M2]], [[Y]] |
| ; CHECK-NEXT: [[AND2:%.*]] = and i1 [[AND1]], [[C2]] |
| ; CHECK-NEXT: ret i1 [[AND2]] |
| ; |
| %x.m1 = and i32 %x, 8 |
| %c1 = icmp eq i32 %x.m1, 8 |
| %and1 = select i1 %c1, i1 %c, i1 false |
| %x.m2 = and i32 %x, %y |
| %c2 = icmp eq i32 %x.m2, %y |
| %and2 = and i1 %and1, %c2 |
| ret i1 %and2 |
| } |
| |
| define i1 @samesign(i32 %x, i32 %y) { |
| ; CHECK-LABEL: @samesign( |
| ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]] |
| ; CHECK-NEXT: [[R:%.*]] = icmp sgt i32 [[TMP1]], -1 |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %a = and i32 %x, %y |
| %lt = icmp slt i32 %a, 0 |
| %o = or i32 %x, %y |
| %gt = icmp sgt i32 %o, -1 |
| %r = or i1 %lt, %gt |
| ret i1 %r |
| } |
| |
| define <2 x i1> @samesign_different_sign_bittest1(<2 x i32> %x, <2 x i32> %y) { |
| ; CHECK-LABEL: @samesign_different_sign_bittest1( |
| ; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i32> [[X:%.*]], [[Y:%.*]] |
| ; CHECK-NEXT: [[R:%.*]] = icmp sgt <2 x i32> [[TMP1]], <i32 -1, i32 -1> |
| ; CHECK-NEXT: ret <2 x i1> [[R]] |
| ; |
| %a = and <2 x i32> %x, %y |
| %lt = icmp sle <2 x i32> %a, <i32 -1, i32 -1> |
| %o = or <2 x i32> %x, %y |
| %gt = icmp sgt <2 x i32> %o, <i32 -1, i32 -1> |
| %r = or <2 x i1> %lt, %gt |
| ret <2 x i1> %r |
| } |
| |
| define i1 @samesign_different_sign_bittest2(i32 %x, i32 %y) { |
| ; CHECK-LABEL: @samesign_different_sign_bittest2( |
| ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]] |
| ; CHECK-NEXT: [[R:%.*]] = icmp sgt i32 [[TMP1]], -1 |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %a = and i32 %x, %y |
| %lt = icmp slt i32 %a, 0 |
| %o = or i32 %x, %y |
| %gt = icmp sge i32 %o, 0 |
| %r = or i1 %lt, %gt |
| ret i1 %r |
| } |
| |
| define i1 @samesign_commute1(i32 %x, i32 %y) { |
| ; CHECK-LABEL: @samesign_commute1( |
| ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]] |
| ; CHECK-NEXT: [[R:%.*]] = icmp sgt i32 [[TMP1]], -1 |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %a = and i32 %x, %y |
| %lt = icmp slt i32 %a, 0 |
| %o = or i32 %x, %y |
| %gt = icmp sgt i32 %o, -1 |
| %r = or i1 %gt, %lt ; compares swapped |
| ret i1 %r |
| } |
| |
| define i1 @samesign_commute2(i32 %x, i32 %y) { |
| ; CHECK-LABEL: @samesign_commute2( |
| ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]] |
| ; CHECK-NEXT: [[R:%.*]] = icmp sgt i32 [[TMP1]], -1 |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %a = and i32 %x, %y |
| %lt = icmp slt i32 %a, 0 |
| %o = or i32 %y, %x ; inputs commuted |
| %gt = icmp sgt i32 %o, -1 |
| %r = or i1 %lt, %gt |
| ret i1 %r |
| } |
| |
| define i1 @samesign_commute3(i32 %x, i32 %y) { |
| ; CHECK-LABEL: @samesign_commute3( |
| ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]] |
| ; CHECK-NEXT: [[R:%.*]] = icmp sgt i32 [[TMP1]], -1 |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %a = and i32 %x, %y |
| %lt = icmp slt i32 %a, 0 |
| %o = or i32 %y, %x ; inputs commuted |
| %gt = icmp sgt i32 %o, -1 |
| %r = or i1 %gt, %lt ; compares swapped |
| ret i1 %r |
| } |
| |
| define i1 @samesign_violate_constraint1(i32 %x, i32 %y) { |
| ; CHECK-LABEL: @samesign_violate_constraint1( |
| ; CHECK-NEXT: [[A:%.*]] = or i32 [[X:%.*]], [[Y:%.*]] |
| ; CHECK-NEXT: [[LT:%.*]] = icmp slt i32 [[A]], 0 |
| ; CHECK-NEXT: [[O:%.*]] = or i32 [[X]], [[Y]] |
| ; CHECK-NEXT: [[GT:%.*]] = icmp sgt i32 [[O]], -1 |
| ; CHECK-NEXT: [[R:%.*]] = and i1 [[LT]], [[GT]] |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %a = or i32 %x, %y |
| %lt = icmp slt i32 %a, 0 |
| %o = or i32 %x, %y ; should be an and |
| %gt = icmp sgt i32 %o, -1 |
| %r = and i1 %lt, %gt |
| ret i1 %r |
| } |
| |
| define i1 @samesign_violate_constraint2(i32 %x, i32 %y) { |
| ; CHECK-LABEL: @samesign_violate_constraint2( |
| ; CHECK-NEXT: [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]] |
| ; CHECK-NEXT: [[LT:%.*]] = icmp slt i32 [[A]], 0 |
| ; CHECK-NEXT: [[O:%.*]] = or i32 [[X]], [[Y]] |
| ; CHECK-NEXT: [[GT:%.*]] = icmp sgt i32 [[O]], -1 |
| ; CHECK-NEXT: [[R:%.*]] = and i1 [[LT]], [[GT]] |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %a = and i32 %x, %y |
| %lt = icmp slt i32 %a, 0 |
| %o = or i32 %x, %y |
| %gt = icmp sgt i32 %o, -1 |
| %r = and i1 %lt, %gt ; should be or |
| ret i1 %r |
| } |
| |
| define i1 @samesign_mult_use(i32 %x, i32 %y) { |
| ; CHECK-LABEL: @samesign_mult_use( |
| ; CHECK-NEXT: [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]] |
| ; CHECK-NEXT: call void @use32(i32 [[A]]) |
| ; CHECK-NEXT: [[O:%.*]] = or i32 [[X]], [[Y]] |
| ; CHECK-NEXT: call void @use32(i32 [[O]]) |
| ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X]], [[Y]] |
| ; CHECK-NEXT: [[R:%.*]] = icmp sgt i32 [[TMP1]], -1 |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %a = and i32 %x, %y |
| call void @use32(i32 %a) |
| %lt = icmp slt i32 %a, 0 |
| %o = or i32 %x, %y |
| call void @use32(i32 %o) |
| %gt = icmp sgt i32 %o, -1 |
| %r = or i1 %lt, %gt |
| ret i1 %r |
| } |
| |
| define i1 @samesign_mult_use2(i32 %x, i32 %y) { |
| ; CHECK-LABEL: @samesign_mult_use2( |
| ; CHECK-NEXT: [[O:%.*]] = or i32 [[X:%.*]], [[Y:%.*]] |
| ; CHECK-NEXT: [[GT:%.*]] = icmp sgt i32 [[O]], -1 |
| ; CHECK-NEXT: call void @use(i1 [[GT]]) |
| ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X]], [[Y]] |
| ; CHECK-NEXT: [[R:%.*]] = icmp sgt i32 [[TMP1]], -1 |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %a = and i32 %x, %y |
| %lt = icmp slt i32 %a, 0 |
| %o = or i32 %x, %y |
| %gt = icmp sgt i32 %o, -1 |
| call void @use(i1 %gt) |
| %r = or i1 %lt, %gt |
| ret i1 %r |
| } |
| |
| define i1 @samesign_mult_use3(i32 %x, i32 %y) { |
| ; CHECK-LABEL: @samesign_mult_use3( |
| ; CHECK-NEXT: [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]] |
| ; CHECK-NEXT: [[LT:%.*]] = icmp slt i32 [[A]], 0 |
| ; CHECK-NEXT: call void @use(i1 [[LT]]) |
| ; CHECK-NEXT: [[O:%.*]] = or i32 [[X]], [[Y]] |
| ; CHECK-NEXT: [[GT:%.*]] = icmp sgt i32 [[O]], -1 |
| ; CHECK-NEXT: call void @use(i1 [[GT]]) |
| ; CHECK-NEXT: [[R:%.*]] = or i1 [[LT]], [[GT]] |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %a = and i32 %x, %y |
| %lt = icmp slt i32 %a, 0 |
| call void @use(i1 %lt) |
| %o = or i32 %x, %y |
| %gt = icmp sgt i32 %o, -1 |
| call void @use(i1 %gt) |
| %r = or i1 %lt, %gt |
| ret i1 %r |
| } |
| |
| define i1 @samesign_wrong_cmp(i32 %x, i32 %y) { |
| ; CHECK-LABEL: @samesign_wrong_cmp( |
| ; CHECK-NEXT: [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]] |
| ; CHECK-NEXT: [[LT:%.*]] = icmp slt i32 [[A]], 1 |
| ; CHECK-NEXT: [[O:%.*]] = or i32 [[X]], [[Y]] |
| ; CHECK-NEXT: [[GT:%.*]] = icmp sgt i32 [[O]], -1 |
| ; CHECK-NEXT: [[R:%.*]] = and i1 [[LT]], [[GT]] |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %a = and i32 %x, %y |
| %lt = icmp slt i32 %a, 1 ; not a sign-bit test |
| %o = or i32 %x, %y |
| %gt = icmp sgt i32 %o, -1 |
| %r = and i1 %lt, %gt |
| ret i1 %r |
| } |
| |
| define i1 @samesign_inverted(i32 %x, i32 %y) { |
| ; CHECK-LABEL: @samesign_inverted( |
| ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]] |
| ; CHECK-NEXT: [[R:%.*]] = icmp slt i32 [[TMP1]], 0 |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %a = and i32 %x, %y |
| %gt = icmp sgt i32 %a, -1 |
| %o = or i32 %x, %y |
| %lt = icmp slt i32 %o, 0 |
| %r = and i1 %gt, %lt |
| ret i1 %r |
| } |
| |
| define i1 @samesign_inverted_different_sign_bittest1(i32 %x, i32 %y) { |
| ; CHECK-LABEL: @samesign_inverted_different_sign_bittest1( |
| ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]] |
| ; CHECK-NEXT: [[R:%.*]] = icmp slt i32 [[TMP1]], 0 |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %a = and i32 %x, %y |
| %gt = icmp sge i32 %a, 0 |
| %o = or i32 %x, %y |
| %lt = icmp slt i32 %o, 0 |
| %r = and i1 %gt, %lt |
| ret i1 %r |
| } |
| |
| define i1 @samesign_inverted_different_sign_bittest2(i32 %x, i32 %y) { |
| ; CHECK-LABEL: @samesign_inverted_different_sign_bittest2( |
| ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]] |
| ; CHECK-NEXT: [[R:%.*]] = icmp slt i32 [[TMP1]], 0 |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %a = and i32 %x, %y |
| %gt = icmp sgt i32 %a, -1 |
| %o = or i32 %x, %y |
| %lt = icmp sle i32 %o, -1 |
| %r = and i1 %gt, %lt |
| ret i1 %r |
| } |
| |
| define i1 @samesign_inverted_commute1(i32 %x, i32 %y) { |
| ; CHECK-LABEL: @samesign_inverted_commute1( |
| ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]] |
| ; CHECK-NEXT: [[R:%.*]] = icmp slt i32 [[TMP1]], 0 |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %a = and i32 %x, %y |
| %gt = icmp sgt i32 %a, -1 |
| %o = or i32 %x, %y |
| %lt = icmp slt i32 %o, 0 |
| %r = and i1 %lt, %gt ; compares swapped |
| ret i1 %r |
| } |
| |
| define i1 @samesign_inverted_commute2(i32 %x, i32 %y) { |
| ; CHECK-LABEL: @samesign_inverted_commute2( |
| ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]] |
| ; CHECK-NEXT: [[R:%.*]] = icmp slt i32 [[TMP1]], 0 |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %a = and i32 %x, %y |
| %gt = icmp sgt i32 %a, -1 |
| %o = or i32 %y, %x ; source values are commuted |
| %lt = icmp slt i32 %o, 0 |
| %r = and i1 %gt, %lt |
| ret i1 %r |
| } |
| |
| define i1 @samesign_inverted_commute3(i32 %x, i32 %y) { |
| ; CHECK-LABEL: @samesign_inverted_commute3( |
| ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]] |
| ; CHECK-NEXT: [[R:%.*]] = icmp slt i32 [[TMP1]], 0 |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %a = and i32 %x, %y |
| %gt = icmp sgt i32 %a, -1 |
| %o = or i32 %y, %x ; source values commuted |
| %lt = icmp slt i32 %o, 0 |
| %r = and i1 %lt, %gt ; compares swapped |
| ret i1 %r |
| } |
| |
| define i1 @samesign_inverted_violate_constraint1(i32 %x, i32 %y) { |
| ; CHECK-LABEL: @samesign_inverted_violate_constraint1( |
| ; CHECK-NEXT: [[A:%.*]] = or i32 [[X:%.*]], [[Y:%.*]] |
| ; CHECK-NEXT: [[GT:%.*]] = icmp sgt i32 [[A]], -1 |
| ; CHECK-NEXT: [[O:%.*]] = and i32 [[X]], [[Y]] |
| ; CHECK-NEXT: [[LT:%.*]] = icmp slt i32 [[O]], 0 |
| ; CHECK-NEXT: [[R:%.*]] = and i1 [[GT]], [[LT]] |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %a = or i32 %x, %y ; should be and here |
| %gt = icmp sgt i32 %a, -1 |
| %o = and i32 %x, %y ; should be or here |
| %lt = icmp slt i32 %o, 0 |
| %r = and i1 %gt, %lt |
| ret i1 %r |
| } |
| define i1 @samesign_inverted_violate_constraint2(i32 %x, i32 %y) { |
| ; CHECK-LABEL: @samesign_inverted_violate_constraint2( |
| ; CHECK-NEXT: [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]] |
| ; CHECK-NEXT: [[GT:%.*]] = icmp sgt i32 [[A]], -1 |
| ; CHECK-NEXT: [[O:%.*]] = or i32 [[X]], [[Y]] |
| ; CHECK-NEXT: [[LT:%.*]] = icmp slt i32 [[O]], 0 |
| ; CHECK-NEXT: [[R:%.*]] = or i1 [[GT]], [[LT]] |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %a = and i32 %x, %y |
| %gt = icmp sgt i32 %a, -1 |
| %o = or i32 %x, %y |
| %lt = icmp slt i32 %o, 0 |
| %r = or i1 %gt, %lt ; should be and here |
| ret i1 %r |
| } |
| |
| define i1 @samesign_inverted_mult_use(i32 %x, i32 %y) { |
| ; CHECK-LABEL: @samesign_inverted_mult_use( |
| ; CHECK-NEXT: [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]] |
| ; CHECK-NEXT: call void @use32(i32 [[A]]) |
| ; CHECK-NEXT: [[O:%.*]] = or i32 [[X]], [[Y]] |
| ; CHECK-NEXT: call void @use32(i32 [[O]]) |
| ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X]], [[Y]] |
| ; CHECK-NEXT: [[R:%.*]] = icmp slt i32 [[TMP1]], 0 |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %a = and i32 %x, %y |
| call void @use32(i32 %a) |
| %gt = icmp sgt i32 %a, -1 |
| %o = or i32 %x, %y |
| call void @use32(i32 %o) |
| %lt = icmp slt i32 %o, 0 |
| %r = and i1 %gt, %lt |
| ret i1 %r |
| } |
| |
| define i1 @samesign_inverted_mult_use2(i32 %x, i32 %y) { |
| ; CHECK-LABEL: @samesign_inverted_mult_use2( |
| ; CHECK-NEXT: [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]] |
| ; CHECK-NEXT: [[GT:%.*]] = icmp sgt i32 [[A]], -1 |
| ; CHECK-NEXT: call void @use(i1 [[GT]]) |
| ; CHECK-NEXT: [[O:%.*]] = or i32 [[X]], [[Y]] |
| ; CHECK-NEXT: [[LT:%.*]] = icmp slt i32 [[O]], 0 |
| ; CHECK-NEXT: call void @use(i1 [[LT]]) |
| ; CHECK-NEXT: [[R:%.*]] = and i1 [[GT]], [[LT]] |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %a = and i32 %x, %y |
| %gt = icmp sgt i32 %a, -1 |
| call void @use(i1 %gt) |
| %o = or i32 %x, %y |
| %lt = icmp slt i32 %o, 0 |
| call void @use(i1 %lt) |
| %r = and i1 %gt, %lt |
| ret i1 %r |
| } |
| |
| define i1 @samesign_inverted_wrong_cmp(i32 %x, i32 %y) { |
| ; CHECK-LABEL: @samesign_inverted_wrong_cmp( |
| ; CHECK-NEXT: [[A:%.*]] = and i32 [[X:%.*]], [[Y:%.*]] |
| ; CHECK-NEXT: [[GT:%.*]] = icmp sgt i32 [[A]], 0 |
| ; CHECK-NEXT: [[O:%.*]] = or i32 [[X]], [[Y]] |
| ; CHECK-NEXT: [[LT:%.*]] = icmp slt i32 [[O]], 0 |
| ; CHECK-NEXT: [[R:%.*]] = and i1 [[GT]], [[LT]] |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %a = and i32 %x, %y |
| %gt = icmp sgt i32 %a, 0 ; not a sign-bit test |
| %o = or i32 %x, %y |
| %lt = icmp slt i32 %o, 0 |
| %r = and i1 %gt, %lt |
| ret i1 %r |
| } |
| |
| define <2 x i1> @icmp_eq_m1_and_eq_m1(<2 x i8> %x, <2 x i8> %y) { |
| ; CHECK-LABEL: @icmp_eq_m1_and_eq_m1( |
| ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], [[Y:%.*]] |
| ; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i8> [[TMP1]], <i8 -1, i8 -1> |
| ; CHECK-NEXT: ret <2 x i1> [[R]] |
| ; |
| %rx = icmp eq <2 x i8> %x, <i8 -1, i8 undef> |
| %ry = icmp eq <2 x i8> %y, <i8 -1, i8 undef> |
| %r = and <2 x i1> %rx, %ry |
| ret <2 x i1> %r |
| } |
| |
| define <2 x i1> @icmp_eq_m1_and_eq_undef_m1(<2 x i8> %x, <2 x i8> %y) { |
| ; CHECK-LABEL: @icmp_eq_m1_and_eq_undef_m1( |
| ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], [[Y:%.*]] |
| ; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i8> [[TMP1]], <i8 -1, i8 -1> |
| ; CHECK-NEXT: ret <2 x i1> [[R]] |
| ; |
| %rx = icmp eq <2 x i8> %x, <i8 -1, i8 undef> |
| %ry = icmp eq <2 x i8> %y, <i8 undef, i8 -1> |
| %r = and <2 x i1> %rx, %ry |
| ret <2 x i1> %r |
| } |
| |
| define <2 x i1> @icmp_eq_undef_and_eq_m1_m2(<2 x i8> %x, <2 x i8> %y) { |
| ; CHECK-LABEL: @icmp_eq_undef_and_eq_m1_m2( |
| ; CHECK-NEXT: ret <2 x i1> zeroinitializer |
| ; |
| %rx = icmp eq <2 x i8> %x, <i8 undef, i8 undef> |
| %ry = icmp eq <2 x i8> %y, <i8 -1, i8 -2> |
| %r = and <2 x i1> %rx, %ry |
| ret <2 x i1> %r |
| } |
| |
| define <2 x i1> @icmp_ne_m1_and_ne_m1_fail(<2 x i8> %x, <2 x i8> %y) { |
| ; CHECK-LABEL: @icmp_ne_m1_and_ne_m1_fail( |
| ; CHECK-NEXT: [[RX:%.*]] = icmp ne <2 x i8> [[X:%.*]], <i8 -1, i8 undef> |
| ; CHECK-NEXT: [[RY:%.*]] = icmp ne <2 x i8> [[Y:%.*]], <i8 -1, i8 undef> |
| ; CHECK-NEXT: [[R:%.*]] = and <2 x i1> [[RX]], [[RY]] |
| ; CHECK-NEXT: ret <2 x i1> [[R]] |
| ; |
| %rx = icmp ne <2 x i8> %x, <i8 -1, i8 undef> |
| %ry = icmp ne <2 x i8> %y, <i8 -1, i8 undef> |
| %r = and <2 x i1> %rx, %ry |
| ret <2 x i1> %r |
| } |
| |
| |
| define <2 x i1> @icmp_eq_m1_or_eq_m1_fail(<2 x i8> %x, <2 x i8> %y) { |
| ; CHECK-LABEL: @icmp_eq_m1_or_eq_m1_fail( |
| ; CHECK-NEXT: [[RX:%.*]] = icmp eq <2 x i8> [[X:%.*]], <i8 -1, i8 undef> |
| ; CHECK-NEXT: [[RY:%.*]] = icmp eq <2 x i8> [[Y:%.*]], <i8 -1, i8 undef> |
| ; CHECK-NEXT: [[R:%.*]] = or <2 x i1> [[RX]], [[RY]] |
| ; CHECK-NEXT: ret <2 x i1> [[R]] |
| ; |
| %rx = icmp eq <2 x i8> %x, <i8 -1, i8 undef> |
| %ry = icmp eq <2 x i8> %y, <i8 -1, i8 undef> |
| %r = or <2 x i1> %rx, %ry |
| ret <2 x i1> %r |
| } |
| |
| |
| define <2 x i1> @icmp_ne_m1_or_ne_m1(<2 x i8> %x, <2 x i8> %y) { |
| ; CHECK-LABEL: @icmp_ne_m1_or_ne_m1( |
| ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], [[Y:%.*]] |
| ; CHECK-NEXT: [[R:%.*]] = icmp ne <2 x i8> [[TMP1]], <i8 -1, i8 -1> |
| ; CHECK-NEXT: ret <2 x i1> [[R]] |
| ; |
| %rx = icmp ne <2 x i8> %x, <i8 -1, i8 -1> |
| %ry = icmp ne <2 x i8> %y, <i8 -1, i8 undef> |
| %r = or <2 x i1> %rx, %ry |
| ret <2 x i1> %r |
| } |
| |
| define i32 @icmp_slt_0_or_icmp_sgt_0_i32(i32 %x) { |
| ; CHECK-LABEL: @icmp_slt_0_or_icmp_sgt_0_i32( |
| ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32 [[X:%.*]], 0 |
| ; CHECK-NEXT: [[E:%.*]] = zext i1 [[TMP1]] to i32 |
| ; CHECK-NEXT: ret i32 [[E]] |
| ; |
| %A = icmp slt i32 %x, 0 |
| %B = icmp sgt i32 %x, 0 |
| %C = zext i1 %A to i32 |
| %D = zext i1 %B to i32 |
| %E = or i32 %C, %D |
| ret i32 %E |
| } |
| |
| define i64 @icmp_slt_0_or_icmp_sgt_0_i64(i64 %x) { |
| ; CHECK-LABEL: @icmp_slt_0_or_icmp_sgt_0_i64( |
| ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i64 [[X:%.*]], 0 |
| ; CHECK-NEXT: [[E:%.*]] = zext i1 [[TMP1]] to i64 |
| ; CHECK-NEXT: ret i64 [[E]] |
| ; |
| %A = icmp slt i64 %x, 0 |
| %B = icmp sgt i64 %x, 0 |
| %C = zext i1 %A to i64 |
| %D = zext i1 %B to i64 |
| %E = or i64 %C, %D |
| ret i64 %E |
| } |
| |
| define i64 @icmp_slt_0_or_icmp_sgt_0_i64_fail0(i64 %x) { |
| ; CHECK-LABEL: @icmp_slt_0_or_icmp_sgt_0_i64_fail0( |
| ; CHECK-NEXT: [[E:%.*]] = lshr i64 [[X:%.*]], 63 |
| ; CHECK-NEXT: ret i64 [[E]] |
| ; |
| %B = icmp slt i64 %x, 0 |
| %C = lshr i64 %x, 63 |
| %D = zext i1 %B to i64 |
| %E = or i64 %C, %D |
| ret i64 %E |
| } |
| |
| define i64 @icmp_slt_0_or_icmp_sgt_0_i64_fail1(i64 %x) { |
| ; CHECK-LABEL: @icmp_slt_0_or_icmp_sgt_0_i64_fail1( |
| ; CHECK-NEXT: [[B:%.*]] = icmp sgt i64 [[X:%.*]], 0 |
| ; CHECK-NEXT: [[C:%.*]] = ashr i64 [[X]], 63 |
| ; CHECK-NEXT: [[D:%.*]] = zext i1 [[B]] to i64 |
| ; CHECK-NEXT: [[E:%.*]] = or i64 [[C]], [[D]] |
| ; CHECK-NEXT: ret i64 [[E]] |
| ; |
| %B = icmp sgt i64 %x, 0 |
| %C = ashr i64 %x, 63 |
| %D = zext i1 %B to i64 |
| %E = or i64 %C, %D |
| ret i64 %E |
| } |
| |
| define i64 @icmp_slt_0_or_icmp_sgt_0_i64_fail2(i64 %x) { |
| ; CHECK-LABEL: @icmp_slt_0_or_icmp_sgt_0_i64_fail2( |
| ; CHECK-NEXT: [[B:%.*]] = icmp sgt i64 [[X:%.*]], 0 |
| ; CHECK-NEXT: [[C:%.*]] = lshr i64 [[X]], 62 |
| ; CHECK-NEXT: [[D:%.*]] = zext i1 [[B]] to i64 |
| ; CHECK-NEXT: [[E:%.*]] = or i64 [[C]], [[D]] |
| ; CHECK-NEXT: ret i64 [[E]] |
| ; |
| %B = icmp sgt i64 %x, 0 |
| %C = lshr i64 %x, 62 |
| %D = zext i1 %B to i64 |
| %E = or i64 %C, %D |
| ret i64 %E |
| } |
| |
| define i64 @icmp_slt_0_or_icmp_sgt_0_i64_fail3(i64 %x) { |
| ; CHECK-LABEL: @icmp_slt_0_or_icmp_sgt_0_i64_fail3( |
| ; CHECK-NEXT: [[C:%.*]] = ashr i64 [[X:%.*]], 62 |
| ; CHECK-NEXT: [[X_LOBIT:%.*]] = lshr i64 [[X]], 63 |
| ; CHECK-NEXT: [[E:%.*]] = or i64 [[C]], [[X_LOBIT]] |
| ; CHECK-NEXT: ret i64 [[E]] |
| ; |
| %B = icmp slt i64 %x, 0 |
| %C = ashr i64 %x, 62 |
| %D = zext i1 %B to i64 |
| %E = or i64 %C, %D |
| ret i64 %E |
| } |
| |
| define <2 x i64> @icmp_slt_0_or_icmp_sgt_0_i64x2(<2 x i64> %x) { |
| ; CHECK-LABEL: @icmp_slt_0_or_icmp_sgt_0_i64x2( |
| ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <2 x i64> [[X:%.*]], zeroinitializer |
| ; CHECK-NEXT: [[E:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i64> |
| ; CHECK-NEXT: ret <2 x i64> [[E]] |
| ; |
| %A = icmp slt <2 x i64> %x, <i64 0,i64 0> |
| %B = icmp sgt <2 x i64> %x, <i64 0,i64 0> |
| %C = zext <2 x i1> %A to <2 x i64> |
| %D = zext <2 x i1> %B to <2 x i64> |
| %E = or <2 x i64> %C, %D |
| ret <2 x i64> %E |
| } |
| |
| define <2 x i64> @icmp_slt_0_or_icmp_sgt_0_i64x2_fail(<2 x i64> %x) { |
| ; CHECK-LABEL: @icmp_slt_0_or_icmp_sgt_0_i64x2_fail( |
| ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt <2 x i64> [[X:%.*]], <i64 1, i64 1> |
| ; CHECK-NEXT: [[E:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i64> |
| ; CHECK-NEXT: ret <2 x i64> [[E]] |
| ; |
| %B = icmp sgt <2 x i64> %x, <i64 1, i64 1> |
| %C = lshr <2 x i64> %x, <i64 63, i64 63> |
| %D = zext <2 x i1> %B to <2 x i64> |
| %E = or <2 x i64> %C, %D |
| ret <2 x i64> %E |
| |
| } |
| |
| define i32 @icmp_slt_0_and_icmp_sge_neg1_i32(i32 %x) { |
| ; CHECK-LABEL: @icmp_slt_0_and_icmp_sge_neg1_i32( |
| ; CHECK-NEXT: ret i32 0 |
| ; |
| %A = icmp sgt i32 %x, -1 |
| %B = zext i1 %A to i32 |
| %C = lshr i32 %x, 31 |
| %D = and i32 %C, %B |
| ret i32 %D |
| } |
| |
| define i32 @icmp_slt_0_or_icmp_sge_neg1_i32(i32 %x) { |
| ; CHECK-LABEL: @icmp_slt_0_or_icmp_sge_neg1_i32( |
| ; CHECK-NEXT: ret i32 1 |
| ; |
| %A = icmp sge i32 %x, -1 |
| %B = zext i1 %A to i32 |
| %C = lshr i32 %x, 31 |
| %D = or i32 %C, %B |
| ret i32 %D |
| } |
| |
| define i32 @icmp_slt_0_or_icmp_sge_100_i32(i32 %x) { |
| ; CHECK-LABEL: @icmp_slt_0_or_icmp_sge_100_i32( |
| ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[X:%.*]], 99 |
| ; CHECK-NEXT: [[D:%.*]] = zext i1 [[TMP1]] to i32 |
| ; CHECK-NEXT: ret i32 [[D]] |
| ; |
| %A = icmp sge i32 %x, 100 |
| %B = zext i1 %A to i32 |
| %C = lshr i32 %x, 31 |
| %D = or i32 %C, %B |
| ret i32 %D |
| } |
| |
| define i64 @icmp_slt_0_and_icmp_sge_neg1_i64(i64 %x) { |
| ; CHECK-LABEL: @icmp_slt_0_and_icmp_sge_neg1_i64( |
| ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[X:%.*]], -1 |
| ; CHECK-NEXT: [[D:%.*]] = zext i1 [[TMP1]] to i64 |
| ; CHECK-NEXT: ret i64 [[D]] |
| ; |
| %A = icmp sge i64 %x, -1 |
| %B = zext i1 %A to i64 |
| %C = lshr i64 %x, 63 |
| %D = and i64 %C, %B |
| ret i64 %D |
| } |
| |
| define i64 @icmp_slt_0_and_icmp_sge_neg2_i64(i64 %x) { |
| ; CHECK-LABEL: @icmp_slt_0_and_icmp_sge_neg2_i64( |
| ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i64 [[X:%.*]], -3 |
| ; CHECK-NEXT: [[D:%.*]] = zext i1 [[TMP1]] to i64 |
| ; CHECK-NEXT: ret i64 [[D]] |
| ; |
| %A = icmp sge i64 %x, -2 |
| %B = zext i1 %A to i64 |
| %C = lshr i64 %x, 63 |
| %D = and i64 %C, %B |
| ret i64 %D |
| } |
| |
| define i64 @ashr_and_icmp_sge_neg1_i64(i64 %x) { |
| ; CHECK-LABEL: @ashr_and_icmp_sge_neg1_i64( |
| ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[X:%.*]], -1 |
| ; CHECK-NEXT: [[D:%.*]] = zext i1 [[TMP1]] to i64 |
| ; CHECK-NEXT: ret i64 [[D]] |
| ; |
| %A = icmp sge i64 %x, -1 |
| %B = zext i1 %A to i64 |
| %C = ashr i64 %x, 63 |
| %D = and i64 %C, %B |
| ret i64 %D |
| } |
| |
| define i64 @icmp_slt_0_and_icmp_sgt_neg1_i64(i64 %x) { |
| ; CHECK-LABEL: @icmp_slt_0_and_icmp_sgt_neg1_i64( |
| ; CHECK-NEXT: ret i64 0 |
| ; |
| %A = icmp sgt i64 %x, -1 |
| %B = zext i1 %A to i64 |
| %C = lshr i64 %x, 63 |
| %D = and i64 %C, %B |
| ret i64 %D |
| } |
| |
| define i64 @icmp_slt_0_and_icmp_sge_neg1_i64_fail(i64 %x) { |
| ; CHECK-LABEL: @icmp_slt_0_and_icmp_sge_neg1_i64_fail( |
| ; CHECK-NEXT: [[A:%.*]] = icmp sgt i64 [[X:%.*]], -2 |
| ; CHECK-NEXT: [[C:%.*]] = lshr i64 [[X]], 62 |
| ; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[C]], 1 |
| ; CHECK-NEXT: [[D:%.*]] = select i1 [[A]], i64 [[TMP1]], i64 0 |
| ; CHECK-NEXT: ret i64 [[D]] |
| ; |
| %A = icmp sge i64 %x, -1 |
| %B = zext i1 %A to i64 |
| %C = lshr i64 %x, 62 |
| %D = and i64 %C, %B |
| ret i64 %D |
| } |
| |
| define <2 x i32> @icmp_slt_0_and_icmp_sge_neg1_i32x2(<2 x i32> %x) { |
| ; CHECK-LABEL: @icmp_slt_0_and_icmp_sge_neg1_i32x2( |
| ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i32> [[X:%.*]], <i32 -1, i32 -1> |
| ; CHECK-NEXT: [[D:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i32> |
| ; CHECK-NEXT: ret <2 x i32> [[D]] |
| ; |
| %A = icmp sge <2 x i32> %x, <i32 -1, i32 -1> |
| %B = zext <2 x i1> %A to <2 x i32> |
| %C = lshr <2 x i32> %x, <i32 31, i32 31> |
| %D = and <2 x i32> %C, %B |
| ret <2 x i32> %D |
| } |
| |
| define <2 x i32> @icmp_slt_0_and_icmp_sge_neg2_i32x2(<2 x i32> %x) { |
| ; CHECK-LABEL: @icmp_slt_0_and_icmp_sge_neg2_i32x2( |
| ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt <2 x i32> [[X:%.*]], <i32 -3, i32 -3> |
| ; CHECK-NEXT: [[D:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i32> |
| ; CHECK-NEXT: ret <2 x i32> [[D]] |
| ; |
| %A = icmp sge <2 x i32> %x, <i32 -2, i32 -2> |
| %B = zext <2 x i1> %A to <2 x i32> |
| %C = lshr <2 x i32> %x, <i32 31, i32 31> |
| %D = and <2 x i32> %C, %B |
| ret <2 x i32> %D |
| } |
| |
| |
| define i32 @icmp_x_slt_0_xor_icmp_y_sgt_neg1_i32(i32 %x, i32 %y) { |
| ; CHECK-LABEL: @icmp_x_slt_0_xor_icmp_y_sgt_neg1_i32( |
| ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]] |
| ; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[TMP1]], -1 |
| ; CHECK-NEXT: [[D:%.*]] = zext i1 [[TMP2]] to i32 |
| ; CHECK-NEXT: ret i32 [[D]] |
| ; |
| %A = icmp sgt i32 %x, -1 |
| %B = zext i1 %A to i32 |
| %C = lshr i32 %y, 31 |
| %D = xor i32 %C, %B |
| ret i32 %D |
| } |
| |
| define i32 @icmp_slt_0_xor_icmp_sgt_neg2_i32(i32 %x) { |
| ; CHECK-LABEL: @icmp_slt_0_xor_icmp_sgt_neg2_i32( |
| ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32 [[X:%.*]], -1 |
| ; CHECK-NEXT: [[D:%.*]] = zext i1 [[TMP1]] to i32 |
| ; CHECK-NEXT: ret i32 [[D]] |
| ; |
| %A = icmp sgt i32 %x, -2 |
| %B = zext i1 %A to i32 |
| %C = lshr i32 %x, 31 |
| %D = xor i32 %C, %B |
| ret i32 %D |
| } |
| |
| define i32 @icmp_slt_0_and_icmp_sge_neg1_i32_multiuse0(i32 %x) { |
| ; CHECK-LABEL: @icmp_slt_0_and_icmp_sge_neg1_i32_multiuse0( |
| ; CHECK-NEXT: [[A:%.*]] = icmp sgt i32 [[X:%.*]], -3 |
| ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[X]], -3 |
| ; CHECK-NEXT: [[D:%.*]] = zext i1 [[TMP1]] to i32 |
| ; CHECK-NEXT: call void @use(i1 [[A]]) |
| ; CHECK-NEXT: ret i32 [[D]] |
| ; |
| %A = icmp sge i32 %x, -2 |
| %B = zext i1 %A to i32 |
| %C = lshr i32 %x, 31 |
| %D = and i32 %C, %B |
| call void @use(i1 %A) |
| ret i32 %D |
| } |
| |
| define i32 @icmp_slt_0_and_icmp_sge_neg2_i32_multiuse1(i32 %x) { |
| ; CHECK-LABEL: @icmp_slt_0_and_icmp_sge_neg2_i32_multiuse1( |
| ; CHECK-NEXT: [[A:%.*]] = icmp sgt i32 [[X:%.*]], -3 |
| ; CHECK-NEXT: [[B:%.*]] = zext i1 [[A]] to i32 |
| ; CHECK-NEXT: [[C:%.*]] = lshr i32 [[X]], 31 |
| ; CHECK-NEXT: [[D:%.*]] = and i32 [[C]], [[B]] |
| ; CHECK-NEXT: call void @use32(i32 [[B]]) |
| ; CHECK-NEXT: ret i32 [[D]] |
| ; |
| %A = icmp sge i32 %x, -2 |
| %B = zext i1 %A to i32 |
| %C = lshr i32 %x, 31 |
| %D = and i32 %C, %B |
| call void @use32(i32 %B) |
| ret i32 %D |
| } |
| |
| define i32 @icmp_slt_0_and_icmp_sge_neg2_i32_multiuse2(i32 %x) { |
| ; CHECK-LABEL: @icmp_slt_0_and_icmp_sge_neg2_i32_multiuse2( |
| ; CHECK-NEXT: [[A:%.*]] = icmp sgt i32 [[X:%.*]], -3 |
| ; CHECK-NEXT: [[C:%.*]] = lshr i32 [[X]], 31 |
| ; CHECK-NEXT: [[D:%.*]] = select i1 [[A]], i32 [[C]], i32 0 |
| ; CHECK-NEXT: call void @use32(i32 [[C]]) |
| ; CHECK-NEXT: ret i32 [[D]] |
| ; |
| %A = icmp sge i32 %x, -2 |
| %B = zext i1 %A to i32 |
| %C = lshr i32 %x, 31 |
| %D = and i32 %C, %B |
| call void @use32(i32 %C) |
| ret i32 %D |
| } |
| |
| define i32 @icmp_slt_0_and_icmp_sge_neg2_i32_multiuse_fail0(i32 %x) { |
| ; CHECK-LABEL: @icmp_slt_0_and_icmp_sge_neg2_i32_multiuse_fail0( |
| ; CHECK-NEXT: [[A:%.*]] = icmp sgt i32 [[X:%.*]], -3 |
| ; CHECK-NEXT: [[B:%.*]] = zext i1 [[A]] to i32 |
| ; CHECK-NEXT: [[C:%.*]] = lshr i32 [[X]], 31 |
| ; CHECK-NEXT: [[D:%.*]] = and i32 [[C]], [[B]] |
| ; CHECK-NEXT: call void @use32(i32 [[B]]) |
| ; CHECK-NEXT: call void @use32(i32 [[C]]) |
| ; CHECK-NEXT: ret i32 [[D]] |
| ; |
| %A = icmp sge i32 %x, -2 |
| %B = zext i1 %A to i32 |
| %C = lshr i32 %x, 31 |
| %D = and i32 %C, %B |
| call void @use32(i32 %B) |
| call void @use32(i32 %C) |
| ret i32 %D |
| } |
| |
| define i32 @icmp_slt_0_or_icmp_eq_100_i32_multiuse_fail1(i32 %x) { |
| ; CHECK-LABEL: @icmp_slt_0_or_icmp_eq_100_i32_multiuse_fail1( |
| ; CHECK-NEXT: [[A:%.*]] = icmp eq i32 [[X:%.*]], 100 |
| ; CHECK-NEXT: [[B:%.*]] = zext i1 [[A]] to i32 |
| ; CHECK-NEXT: [[C:%.*]] = lshr i32 [[X]], 31 |
| ; CHECK-NEXT: [[D:%.*]] = or i32 [[C]], [[B]] |
| ; CHECK-NEXT: call void @use32(i32 [[C]]) |
| ; CHECK-NEXT: ret i32 [[D]] |
| ; |
| %A = icmp eq i32 %x, 100 |
| %B = zext i1 %A to i32 |
| %C = lshr i32 %x, 31 |
| %D = or i32 %C, %B |
| call void @use32(i32 %C) |
| ret i32 %D |
| } |
| |
| define i32 @icmp_x_slt_0_and_icmp_y_ne_neg2_i32_multiuse_fail2(i32 %x, i32 %y) { |
| ; CHECK-LABEL: @icmp_x_slt_0_and_icmp_y_ne_neg2_i32_multiuse_fail2( |
| ; CHECK-NEXT: [[A_NOT:%.*]] = icmp eq i32 [[X:%.*]], -2 |
| ; CHECK-NEXT: [[C:%.*]] = lshr i32 [[Y:%.*]], 31 |
| ; CHECK-NEXT: [[D:%.*]] = select i1 [[A_NOT]], i32 0, i32 [[C]] |
| ; CHECK-NEXT: call void @use32(i32 [[C]]) |
| ; CHECK-NEXT: ret i32 [[D]] |
| ; |
| %A = icmp ne i32 %x, -2 |
| %B = zext i1 %A to i32 |
| %C = lshr i32 %y, 31 |
| %D = and i32 %C |