| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py |
| ; RUN: opt < %s -passes=instcombine -S | FileCheck %s |
| |
| ; No selects should remain. |
| |
| define i41 @zext(i1 %C) { |
| ; CHECK-LABEL: @zext( |
| ; CHECK-NEXT: [[V:%.*]] = zext i1 [[C:%.*]] to i41 |
| ; CHECK-NEXT: ret i41 [[V]] |
| ; |
| %V = select i1 %C, i41 1, i41 0 |
| ret i41 %V |
| } |
| |
| define i41 @sext(i1 %C) { |
| ; CHECK-LABEL: @sext( |
| ; CHECK-NEXT: [[V:%.*]] = sext i1 [[C:%.*]] to i41 |
| ; CHECK-NEXT: ret i41 [[V]] |
| ; |
| %V = select i1 %C, i41 -1, i41 0 |
| ret i41 %V |
| } |
| |
| define i999 @not_zext(i1 %C) { |
| ; CHECK-LABEL: @not_zext( |
| ; CHECK-NEXT: [[NOT_C:%.*]] = xor i1 [[C:%.*]], true |
| ; CHECK-NEXT: [[V:%.*]] = zext i1 [[NOT_C]] to i999 |
| ; CHECK-NEXT: ret i999 [[V]] |
| ; |
| %V = select i1 %C, i999 0, i999 1 |
| ret i999 %V |
| } |
| |
| define i999 @not_sext(i1 %C) { |
| ; CHECK-LABEL: @not_sext( |
| ; CHECK-NEXT: [[NOT_C:%.*]] = xor i1 [[C:%.*]], true |
| ; CHECK-NEXT: [[V:%.*]] = sext i1 [[NOT_C]] to i999 |
| ; CHECK-NEXT: ret i999 [[V]] |
| ; |
| %V = select i1 %C, i999 0, i999 -1 |
| ret i999 %V |
| } |
| |
| ; Vector selects of vector splat constants match APInt too. |
| |
| define <2 x i41> @zext_vec(<2 x i1> %C) { |
| ; CHECK-LABEL: @zext_vec( |
| ; CHECK-NEXT: [[V:%.*]] = zext <2 x i1> [[C:%.*]] to <2 x i41> |
| ; CHECK-NEXT: ret <2 x i41> [[V]] |
| ; |
| %V = select <2 x i1> %C, <2 x i41> <i41 1, i41 1>, <2 x i41> <i41 0, i41 0> |
| ret <2 x i41> %V |
| } |
| |
| define <2 x i32> @sext_vec(<2 x i1> %C) { |
| ; CHECK-LABEL: @sext_vec( |
| ; CHECK-NEXT: [[V:%.*]] = sext <2 x i1> [[C:%.*]] to <2 x i32> |
| ; CHECK-NEXT: ret <2 x i32> [[V]] |
| ; |
| %V = select <2 x i1> %C, <2 x i32> <i32 -1, i32 -1>, <2 x i32> <i32 0, i32 0> |
| ret <2 x i32> %V |
| } |
| |
| define <2 x i999> @not_zext_vec(<2 x i1> %C) { |
| ; CHECK-LABEL: @not_zext_vec( |
| ; CHECK-NEXT: [[NOT_C:%.*]] = xor <2 x i1> [[C:%.*]], <i1 true, i1 true> |
| ; CHECK-NEXT: [[V:%.*]] = zext <2 x i1> [[NOT_C]] to <2 x i999> |
| ; CHECK-NEXT: ret <2 x i999> [[V]] |
| ; |
| %V = select <2 x i1> %C, <2 x i999> <i999 0, i999 0>, <2 x i999> <i999 1, i999 1> |
| ret <2 x i999> %V |
| } |
| |
| define <2 x i64> @not_sext_vec(<2 x i1> %C) { |
| ; CHECK-LABEL: @not_sext_vec( |
| ; CHECK-NEXT: [[NOT_C:%.*]] = xor <2 x i1> [[C:%.*]], <i1 true, i1 true> |
| ; CHECK-NEXT: [[V:%.*]] = sext <2 x i1> [[NOT_C]] to <2 x i64> |
| ; CHECK-NEXT: ret <2 x i64> [[V]] |
| ; |
| %V = select <2 x i1> %C, <2 x i64> <i64 0, i64 0>, <2 x i64> <i64 -1, i64 -1> |
| ret <2 x i64> %V |
| } |
| |
| ; But don't touch this - we would need 3 instructions to extend and splat the scalar select condition. |
| |
| define <2 x i32> @scalar_select_of_vectors(i1 %c) { |
| ; CHECK-LABEL: @scalar_select_of_vectors( |
| ; CHECK-NEXT: [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 1, i32 1>, <2 x i32> zeroinitializer |
| ; CHECK-NEXT: ret <2 x i32> [[V]] |
| ; |
| %V = select i1 %c, <2 x i32> <i32 1, i32 1>, <2 x i32> zeroinitializer |
| ret <2 x i32> %V |
| } |
| |
| ;; (x <s 0) ? -1 : 0 -> ashr x, 31 |
| |
| define i41 @test3(i41 %X) { |
| ; CHECK-LABEL: @test3( |
| ; CHECK-NEXT: [[X_LOBIT:%.*]] = ashr i41 [[X:%.*]], 40 |
| ; CHECK-NEXT: ret i41 [[X_LOBIT]] |
| ; |
| %t = icmp slt i41 %X, 0 |
| %V = select i1 %t, i41 -1, i41 0 |
| ret i41 %V |
| } |
| |
| ;; (x <s 0) ? -1 : 0 -> ashr x, 31 |
| |
| define i1023 @test4(i1023 %X) { |
| ; CHECK-LABEL: @test4( |
| ; CHECK-NEXT: [[X_LOBIT:%.*]] = ashr i1023 [[X:%.*]], 1022 |
| ; CHECK-NEXT: ret i1023 [[X_LOBIT]] |
| ; |
| %t = icmp slt i1023 %X, 0 |
| %V = select i1 %t, i1023 -1, i1023 0 |
| ret i1023 %V |
| } |
| |