| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py |
| ; RUN: opt < %s -passes=instcombine -S | FileCheck %s |
| |
| declare void @use_double(double) |
| |
| ;; ============================================================ |
| ;; Core pattern: fcmp une (select C1, K, K'), (select C2, K, K') → xor |
| ;; Truth table: {(0,0):false, (0,1):true, (1,0):true, (1,1):false} = 0b0110 |
| ;; ============================================================ |
| |
| define i1 @fcmp_une_select_same_consts(double %a, double %b) { |
| ; CHECK-LABEL: @fcmp_une_select_same_consts( |
| ; CHECK-NEXT: [[V0:%.*]] = fcmp ult double [[B:%.*]], 0.000000e+00 |
| ; CHECK-NEXT: [[V2:%.*]] = fcmp ult double [[A:%.*]], 0.000000e+00 |
| ; CHECK-NEXT: [[V4:%.*]] = xor i1 [[V0]], [[V2]] |
| ; CHECK-NEXT: ret i1 [[V4]] |
| ; |
| %v0 = fcmp ult double %b, 0.000000e+00 |
| %v1 = select i1 %v0, double -1.000000e+00, double 1.000000e+00 |
| %v2 = fcmp ult double %a, 0.000000e+00 |
| %v3 = select i1 %v2, double -1.000000e+00, double 1.000000e+00 |
| %v4 = fcmp une double %v1, %v3 |
| ret i1 %v4 |
| } |
| |
| ;; ============================================================ |
| ;; fcmp oeq → xnor |
| ;; Truth table: 0b1001 |
| ;; ============================================================ |
| |
| define i1 @fcmp_oeq_select_same_consts(double %a, double %b) { |
| ; CHECK-LABEL: @fcmp_oeq_select_same_consts( |
| ; CHECK-NEXT: [[V0:%.*]] = fcmp ult double [[B:%.*]], 0.000000e+00 |
| ; CHECK-NEXT: [[TMP1:%.*]] = fcmp oge double [[A:%.*]], 0.000000e+00 |
| ; CHECK-NEXT: [[V4:%.*]] = xor i1 [[V0]], [[TMP1]] |
| ; CHECK-NEXT: ret i1 [[V4]] |
| ; |
| %v0 = fcmp ult double %b, 0.000000e+00 |
| %v1 = select i1 %v0, double -1.000000e+00, double 1.000000e+00 |
| %v2 = fcmp ult double %a, 0.000000e+00 |
| %v3 = select i1 %v2, double -1.000000e+00, double 1.000000e+00 |
| %v4 = fcmp oeq double %v1, %v3 |
| ret i1 %v4 |
| } |
| |
| ;; ============================================================ |
| ;; fcmp one (ordered not-equal) → xor (same as une for non-NaN) |
| ;; ============================================================ |
| |
| define i1 @fcmp_one_select_same_consts(double %a, double %b) { |
| ; CHECK-LABEL: @fcmp_one_select_same_consts( |
| ; CHECK-NEXT: [[V0:%.*]] = fcmp ult double [[B:%.*]], 0.000000e+00 |
| ; CHECK-NEXT: [[V2:%.*]] = fcmp ult double [[A:%.*]], 0.000000e+00 |
| ; CHECK-NEXT: [[V4:%.*]] = xor i1 [[V0]], [[V2]] |
| ; CHECK-NEXT: ret i1 [[V4]] |
| ; |
| %v0 = fcmp ult double %b, 0.000000e+00 |
| %v1 = select i1 %v0, double -1.000000e+00, double 1.000000e+00 |
| %v2 = fcmp ult double %a, 0.000000e+00 |
| %v3 = select i1 %v2, double -1.000000e+00, double 1.000000e+00 |
| %v4 = fcmp one double %v1, %v3 |
| ret i1 %v4 |
| } |
| |
| ;; ============================================================ |
| ;; fcmp ueq → xnor (same as oeq for non-NaN) |
| ;; ============================================================ |
| |
| define i1 @fcmp_ueq_select_same_consts(double %a, double %b) { |
| ; CHECK-LABEL: @fcmp_ueq_select_same_consts( |
| ; CHECK-NEXT: [[V0:%.*]] = fcmp ult double [[B:%.*]], 0.000000e+00 |
| ; CHECK-NEXT: [[TMP1:%.*]] = fcmp oge double [[A:%.*]], 0.000000e+00 |
| ; CHECK-NEXT: [[V4:%.*]] = xor i1 [[V0]], [[TMP1]] |
| ; CHECK-NEXT: ret i1 [[V4]] |
| ; |
| %v0 = fcmp ult double %b, 0.000000e+00 |
| %v1 = select i1 %v0, double -1.000000e+00, double 1.000000e+00 |
| %v2 = fcmp ult double %a, 0.000000e+00 |
| %v3 = select i1 %v2, double -1.000000e+00, double 1.000000e+00 |
| %v4 = fcmp ueq double %v1, %v3 |
| ret i1 %v4 |
| } |
| |
| ;; ============================================================ |
| ;; Swapped constants: (select C1, K1, K2) vs (select C2, K2, K1) |
| ;; une with swapped → truth table 0b1001 → xnor |
| ;; ============================================================ |
| |
| define i1 @fcmp_une_select_swapped_consts(double %a, double %b) { |
| ; CHECK-LABEL: @fcmp_une_select_swapped_consts( |
| ; CHECK-NEXT: [[V0:%.*]] = fcmp ult double [[B:%.*]], 0.000000e+00 |
| ; CHECK-NEXT: [[TMP1:%.*]] = fcmp oge double [[A:%.*]], 0.000000e+00 |
| ; CHECK-NEXT: [[V4:%.*]] = xor i1 [[V0]], [[TMP1]] |
| ; CHECK-NEXT: ret i1 [[V4]] |
| ; |
| %v0 = fcmp ult double %b, 0.000000e+00 |
| %v1 = select i1 %v0, double -1.000000e+00, double 1.000000e+00 |
| %v2 = fcmp ult double %a, 0.000000e+00 |
| %v3 = select i1 %v2, double 1.000000e+00, double -1.000000e+00 |
| %v4 = fcmp une double %v1, %v3 |
| ret i1 %v4 |
| } |
| |
| ;; ============================================================ |
| ;; Different constant pairs (not just -1/+1) |
| ;; ============================================================ |
| |
| define i1 @fcmp_une_select_other_consts(double %a, double %b) { |
| ; CHECK-LABEL: @fcmp_une_select_other_consts( |
| ; CHECK-NEXT: [[V0:%.*]] = fcmp olt double [[B:%.*]], 5.000000e+00 |
| ; CHECK-NEXT: [[V2:%.*]] = fcmp olt double [[A:%.*]], 5.000000e+00 |
| ; CHECK-NEXT: [[V4:%.*]] = xor i1 [[V0]], [[V2]] |
| ; CHECK-NEXT: ret i1 [[V4]] |
| ; |
| %v0 = fcmp olt double %b, 5.000000e+00 |
| %v1 = select i1 %v0, double 4.200000e+01, double 1.337000e+02 |
| %v2 = fcmp olt double %a, 5.000000e+00 |
| %v3 = select i1 %v2, double 4.200000e+01, double 1.337000e+02 |
| %v4 = fcmp une double %v1, %v3 |
| ret i1 %v4 |
| } |
| |
| ;; ============================================================ |
| ;; Float type (not just double) |
| ;; ============================================================ |
| |
| define i1 @fcmp_une_select_float(float %a, float %b) { |
| ; CHECK-LABEL: @fcmp_une_select_float( |
| ; CHECK-NEXT: [[V0:%.*]] = fcmp ult float [[B:%.*]], 0.000000e+00 |
| ; CHECK-NEXT: [[V2:%.*]] = fcmp ult float [[A:%.*]], 0.000000e+00 |
| ; CHECK-NEXT: [[V4:%.*]] = xor i1 [[V0]], [[V2]] |
| ; CHECK-NEXT: ret i1 [[V4]] |
| ; |
| %v0 = fcmp ult float %b, 0.000000e+00 |
| %v1 = select i1 %v0, float -1.000000e+00, float 1.000000e+00 |
| %v2 = fcmp ult float %a, 0.000000e+00 |
| %v3 = select i1 %v2, float -1.000000e+00, float 1.000000e+00 |
| %v4 = fcmp une float %v1, %v3 |
| ret i1 %v4 |
| } |
| |
| ;; ============================================================ |
| ;; Relational predicate: olt → now folds via truth table |
| ;; Truth table: 0b0100 → and(C1, not(C2)) |
| ;; ============================================================ |
| |
| define i1 @fcmp_olt_select(double %a, double %b) { |
| ; CHECK-LABEL: @fcmp_olt_select( |
| ; CHECK-NEXT: [[V2:%.*]] = fcmp ult double [[A:%.*]], 0.000000e+00 |
| ; CHECK-NEXT: [[V3:%.*]] = fcmp oge double [[A1:%.*]], 0.000000e+00 |
| ; CHECK-NEXT: [[V4:%.*]] = and i1 [[V2]], [[V3]] |
| ; CHECK-NEXT: ret i1 [[V4]] |
| ; |
| %v0 = fcmp ult double %b, 0.000000e+00 |
| %v1 = select i1 %v0, double -1.000000e+00, double 1.000000e+00 |
| %v2 = fcmp ult double %a, 0.000000e+00 |
| %v3 = select i1 %v2, double -1.000000e+00, double 1.000000e+00 |
| %v4 = fcmp olt double %v1, %v3 |
| ret i1 %v4 |
| } |
| |
| ;; ============================================================ |
| ;; Relational predicate: ogt → truth table 0b0010 |
| ;; → and(not(C1), C2) |
| ;; ============================================================ |
| |
| define i1 @fcmp_ogt_select(double %a, double %b) { |
| ; CHECK-LABEL: @fcmp_ogt_select( |
| ; CHECK-NEXT: [[V0:%.*]] = fcmp oge double [[B:%.*]], 0.000000e+00 |
| ; CHECK-NEXT: [[V2:%.*]] = fcmp ult double [[A:%.*]], 0.000000e+00 |
| ; CHECK-NEXT: [[V4:%.*]] = and i1 [[V0]], [[V2]] |
| ; CHECK-NEXT: ret i1 [[V4]] |
| ; |
| %v0 = fcmp ult double %b, 0.000000e+00 |
| %v1 = select i1 %v0, double -1.000000e+00, double 1.000000e+00 |
| %v2 = fcmp ult double %a, 0.000000e+00 |
| %v3 = select i1 %v2, double -1.000000e+00, double 1.000000e+00 |
| %v4 = fcmp ogt double %v1, %v3 |
| ret i1 %v4 |
| } |
| |
| ;; ============================================================ |
| ;; Vector type |
| ;; ============================================================ |
| |
| define <2 x i1> @fcmp_une_select_vec(<2 x double> %a, <2 x double> %b) { |
| ; CHECK-LABEL: @fcmp_une_select_vec( |
| ; CHECK-NEXT: [[V0:%.*]] = fcmp ult <2 x double> [[B:%.*]], zeroinitializer |
| ; CHECK-NEXT: [[V2:%.*]] = fcmp ult <2 x double> [[A:%.*]], zeroinitializer |
| ; CHECK-NEXT: [[V4:%.*]] = xor <2 x i1> [[V0]], [[V2]] |
| ; CHECK-NEXT: ret <2 x i1> [[V4]] |
| ; |
| %v0 = fcmp ult <2 x double> %b, zeroinitializer |
| %v1 = select <2 x i1> %v0, <2 x double> <double -1.0, double -1.0>, <2 x double> <double 1.0, double 1.0> |
| %v2 = fcmp ult <2 x double> %a, zeroinitializer |
| %v3 = select <2 x i1> %v2, <2 x double> <double -1.0, double -1.0>, <2 x double> <double 1.0, double 1.0> |
| %v4 = fcmp une <2 x double> %v1, %v3 |
| ret <2 x i1> %v4 |
| } |
| |
| ;; ============================================================ |
| ;; Negative: vector constant folding can yield a mixed mask like |
| ;; <i1 true, i1 false>, so the truth-table fold must bail out. |
| ;; ============================================================ |
| |
| define <2 x i1> @fcmp_une_select_vec_mixed_mask_no_fold(<2 x i1> %c0, <2 x i1> %c1) { |
| ; CHECK-LABEL: @fcmp_une_select_vec_mixed_mask_no_fold( |
| ; CHECK-NEXT: [[S0:%.*]] = select <2 x i1> [[C0:%.*]], <2 x double> <double 1.000000e+00, double 2.000000e+00>, <2 x double> <double 3.000000e+00, double 4.000000e+00> |
| ; CHECK-NEXT: [[S1:%.*]] = select <2 x i1> [[C1:%.*]], <2 x double> <double 1.000000e+00, double 9.000000e+00>, <2 x double> <double 8.000000e+00, double 4.000000e+00> |
| ; CHECK-NEXT: [[R:%.*]] = fcmp une <2 x double> [[S0]], [[S1]] |
| ; CHECK-NEXT: ret <2 x i1> [[R]] |
| %s0 = select <2 x i1> %c0, |
| <2 x double> <double 1.0, double 2.0>, |
| <2 x double> <double 3.0, double 4.0> |
| %s1 = select <2 x i1> %c1, |
| <2 x double> <double 1.0, double 9.0>, |
| <2 x double> <double 8.0, double 4.0> |
| %r = fcmp une <2 x double> %s0, %s1 |
| ret <2 x i1> %r |
| } |
| |
| ;; ============================================================ |
| ;; Multi-use: une (xor) still folds — xor is single instruction |
| ;; ============================================================ |
| |
| define i1 @fcmp_une_select_multi_use(double %a, double %b) { |
| ; CHECK-LABEL: @fcmp_une_select_multi_use( |
| ; CHECK-NEXT: [[V0:%.*]] = fcmp ult double [[B:%.*]], 0.000000e+00 |
| ; CHECK-NEXT: [[V1:%.*]] = select i1 [[V0]], double -1.000000e+00, double 1.000000e+00 |
| ; CHECK-NEXT: [[V2:%.*]] = fcmp ult double [[A:%.*]], 0.000000e+00 |
| ; CHECK-NEXT: [[V3:%.*]] = select i1 [[V2]], double -1.000000e+00, double 1.000000e+00 |
| ; CHECK-NEXT: call void @use_double(double [[V1]]) |
| ; CHECK-NEXT: call void @use_double(double [[V3]]) |
| ; CHECK-NEXT: [[V4:%.*]] = xor i1 [[V0]], [[V2]] |
| ; CHECK-NEXT: ret i1 [[V4]] |
| ; |
| %v0 = fcmp ult double %b, 0.000000e+00 |
| %v1 = select i1 %v0, double -1.000000e+00, double 1.000000e+00 |
| %v2 = fcmp ult double %a, 0.000000e+00 |
| %v3 = select i1 %v2, double -1.000000e+00, double 1.000000e+00 |
| call void @use_double(double %v1) |
| call void @use_double(double %v3) |
| %v4 = fcmp une double %v1, %v3 |
| ret i1 %v4 |
| } |
| |
| ;; ============================================================ |
| ;; Negative: multi-use + olt (needs 2 instructions, HasOneUse=false) |
| ;; → createLogicFromTable returns nullptr |
| ;; ============================================================ |
| |
| define i1 @fcmp_olt_select_multi_use_no_fold(double %a, double %b) { |
| ; CHECK-LABEL: @fcmp_olt_select_multi_use_no_fold( |
| ; CHECK-NEXT: [[V0:%.*]] = fcmp ult double [[B:%.*]], 0.000000e+00 |
| ; CHECK-NEXT: [[V1:%.*]] = select i1 [[V0]], double -1.000000e+00, double 1.000000e+00 |
| ; CHECK-NEXT: [[V2:%.*]] = fcmp ult double [[A:%.*]], 0.000000e+00 |
| ; CHECK-NEXT: [[V3:%.*]] = select i1 [[V2]], double -1.000000e+00, double 1.000000e+00 |
| ; CHECK-NEXT: call void @use_double(double [[V1]]) |
| ; CHECK-NEXT: call void @use_double(double [[V3]]) |
| ; CHECK-NEXT: [[V4:%.*]] = fcmp olt double [[V1]], [[V3]] |
| ; CHECK-NEXT: ret i1 [[V4]] |
| ; |
| %v0 = fcmp ult double %b, 0.000000e+00 |
| %v1 = select i1 %v0, double -1.000000e+00, double 1.000000e+00 |
| %v2 = fcmp ult double %a, 0.000000e+00 |
| %v3 = select i1 %v2, double -1.000000e+00, double 1.000000e+00 |
| call void @use_double(double %v1) |
| call void @use_double(double %v3) |
| %v4 = fcmp olt double %v1, %v3 |
| ret i1 %v4 |
| } |
| |
| ;; ============================================================ |
| ;; Negative: constants are the same (K1 == K2) |
| ;; Selects simplify to constant, fcmp une → false |
| ;; ============================================================ |
| |
| define i1 @fcmp_une_select_same_val(double %a, double %b) { |
| ; CHECK-LABEL: @fcmp_une_select_same_val( |
| ; CHECK-NEXT: ret i1 false |
| ; |
| %v0 = fcmp ult double %b, 0.000000e+00 |
| %v1 = select i1 %v0, double 1.000000e+00, double 1.000000e+00 |
| %v2 = fcmp ult double %a, 0.000000e+00 |
| %v3 = select i1 %v2, double 1.000000e+00, double 1.000000e+00 |
| %v4 = fcmp une double %v1, %v3 |
| ret i1 %v4 |
| } |
| |
| ;; ============================================================ |
| ;; Different constant pairs across selects |
| ;; All 4 combinations yield une=true → constant true |
| ;; ============================================================ |
| |
| define i1 @fcmp_une_select_diff_pairs(double %a, double %b) { |
| ; CHECK-LABEL: @fcmp_une_select_diff_pairs( |
| ; CHECK-NEXT: ret i1 true |
| ; |
| %v0 = fcmp ult double %b, 0.000000e+00 |
| %v1 = select i1 %v0, double -1.000000e+00, double 1.000000e+00 |
| %v2 = fcmp ult double %a, 0.000000e+00 |
| %v3 = select i1 %v2, double -2.000000e+00, double 3.000000e+00 |
| %v4 = fcmp une double %v1, %v3 |
| ret i1 %v4 |
| } |
| |
| ;; ============================================================ |
| ;; icmp ne with select of integer constants → xor |
| ;; Truth table: 0b0110 |
| ;; ============================================================ |
| |
| define i1 @icmp_ne_select_consts(i32 %a, i32 %b) { |
| ; CHECK-LABEL: @icmp_ne_select_consts( |
| ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B:%.*]], [[A:%.*]] |
| ; CHECK-NEXT: [[R:%.*]] = icmp slt i32 [[TMP1]], 0 |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %s1 = icmp slt i32 %a, 0 |
| %v1 = select i1 %s1, i32 -1, i32 1 |
| %s2 = icmp slt i32 %b, 0 |
| %v2 = select i1 %s2, i32 -1, i32 1 |
| %r = icmp ne i32 %v1, %v2 |
| ret i1 %r |
| } |
| |
| ;; ============================================================ |
| ;; icmp eq with select of integer constants → xnor |
| ;; Truth table: 0b1001 |
| ;; ============================================================ |
| |
| define i1 @icmp_eq_select_consts(i32 %a, i32 %b) { |
| ; CHECK-LABEL: @icmp_eq_select_consts( |
| ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B:%.*]], [[A:%.*]] |
| ; CHECK-NEXT: [[R:%.*]] = icmp sgt i32 [[TMP1]], -1 |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %s1 = icmp slt i32 %a, 0 |
| %v1 = select i1 %s1, i32 -1, i32 1 |
| %s2 = icmp slt i32 %b, 0 |
| %v2 = select i1 %s2, i32 -1, i32 1 |
| %r = icmp eq i32 %v1, %v2 |
| ret i1 %r |
| } |
| |
| ;; ============================================================ |
| ;; icmp slt with select of integer constants |
| ;; Truth table: 0b0100 → and(C1, not(C2)) |
| ;; ============================================================ |
| |
| define i1 @icmp_slt_select_consts(i32 %a, i32 %b) { |
| ; CHECK-LABEL: @icmp_slt_select_consts( |
| ; CHECK-NEXT: [[S1_INV:%.*]] = icmp slt i32 [[A:%.*]], 0 |
| ; CHECK-NEXT: [[S2_INV:%.*]] = icmp sgt i32 [[B:%.*]], -1 |
| ; CHECK-NEXT: [[R:%.*]] = select i1 [[S1_INV]], i1 [[S2_INV]], i1 false |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %s1 = icmp slt i32 %a, 0 |
| %v1 = select i1 %s1, i32 -1, i32 1 |
| %s2 = icmp slt i32 %b, 0 |
| %v2 = select i1 %s2, i32 -1, i32 1 |
| %r = icmp slt i32 %v1, %v2 |
| ret i1 %r |
| } |
| |
| ;; ============================================================ |
| ;; icmp with swapped integer constants |
| ;; icmp ne (select C1, -1, 1), (select C2, 1, -1) |
| ;; Truth table: 0b1001 → xnor |
| ;; ============================================================ |
| |
| define i1 @icmp_ne_select_swapped_consts(i32 %a, i32 %b) { |
| ; CHECK-LABEL: @icmp_ne_select_swapped_consts( |
| ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[B:%.*]], [[A:%.*]] |
| ; CHECK-NEXT: [[R:%.*]] = icmp sgt i32 [[TMP1]], -1 |
| ; CHECK-NEXT: ret i1 [[R]] |
| ; |
| %s1 = icmp slt i32 %a, 0 |
| %v1 = select i1 %s1, i32 -1, i32 1 |
| %s2 = icmp slt i32 %b, 0 |
| %v2 = select i1 %s2, i32 1, i32 -1 |
| %r = icmp ne i32 %v1, %v2 |
| ret i1 %r |
| } |
| |
| ;; ============================================================ |
| ;; Negative: vector condition should not fold via truth table. |
| ;; ConstantFoldCompareInstOperands may yield a mixed mask like |
| ;; <i1 true, i1 false>, so we must bail out. |
| ;; ============================================================ |
| |
| define <2 x i1> @icmp_eq_select_vec_cond_no_fold(<2 x i1> %c1, <2 x i1> %c2) { |
| ; CHECK-LABEL: @icmp_eq_select_vec_cond_no_fold( |
| ; CHECK-NEXT: [[S1:%.*]] = select <2 x i1> [[C1:%.*]], <2 x i32> <i32 1, i32 2>, <2 x i32> <i32 3, i32 4> |
| ; CHECK-NEXT: [[S2:%.*]] = select <2 x i1> [[C2:%.*]], <2 x i32> <i32 1, i32 9>, <2 x i32> <i32 8, i32 4> |
| ; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i32> [[S1]], [[S2]] |
| ; CHECK-NEXT: ret <2 x i1> [[R]] |
| ; |
| %s1 = select <2 x i1> %c1, |
| <2 x i32> <i32 1, i32 2>, |
| <2 x i32> <i32 3, i32 4> |
| %s2 = select <2 x i1> %c2, |
| <2 x i32> <i32 1, i32 9>, |
| <2 x i32> <i32 8, i32 4> |
| %r = icmp eq <2 x i32> %s1, %s2 |
| ret <2 x i1> %r |
| } |
| |
| ;; ============================================================ |
| ;; Negative: mixed vector/scalar select conditions should not |
| ;; fold via truth table. |
| ;; ============================================================ |
| |
| define <2 x i1> @icmp_eq_mixed_cond_no_fold(<2 x i1> %c1, i1 %c2) { |
| ; CHECK-LABEL: @icmp_eq_mixed_cond_no_fold( |
| ; CHECK-NEXT: [[S1:%.*]] = select <2 x i1> [[C1:%.*]], <2 x i32> <i32 1, i32 2>, <2 x i32> <i32 3, i32 4> |
| ; CHECK-NEXT: [[S2:%.*]] = select i1 [[C2:%.*]], <2 x i32> <i32 1, i32 9>, <2 x i32> <i32 8, i32 4> |
| ; CHECK-NEXT: [[R:%.*]] = icmp eq <2 x i32> [[S1]], [[S2]] |
| ; CHECK-NEXT: ret <2 x i1> [[R]] |
| ; |
| %s1 = select <2 x i1> %c1, |
| <2 x i32> <i32 1, i32 2>, |
| <2 x i32> <i32 3, i32 4> |
| %s2 = select i1 %c2, |
| <2 x i32> <i32 1, i32 9>, |
| <2 x i32> <i32 8, i32 4> |
| %r = icmp eq <2 x i32> %s1, %s2 |
| ret <2 x i1> %r |
| } |