diff --git a/llvm/test/Transforms/InstCombine/select_and_icmpeq.ll b/llvm/test/Transforms/InstCombine/select_and_icmpeq.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/select_and_icmpeq.ll @@ -0,0 +1,169 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -passes=instcombine -S | FileCheck %s + +declare void @use32(i32) +declare void @use16(i16) +declare void @use7(i7) +declare void @use3(i3) + +define i1 @select_and_icmpeq_i32_commuted1(i1 %x, i1 %y) { +; CHECK-LABEL: @select_and_icmpeq_i32_commuted1( +; CHECK-NEXT: [[S1:%.*]] = select i1 [[X:%.*]], i32 2, i32 1 +; CHECK-NEXT: [[S2:%.*]] = select i1 [[Y:%.*]], i32 2, i32 1 +; CHECK-NEXT: [[AND:%.*]] = and i32 [[S1]], [[S2]] +; CHECK-NEXT: [[ICMP:%.*]] = icmp eq i32 [[AND]], 0 +; CHECK-NEXT: ret i1 [[ICMP]] +; + %s1 = select i1 %x, i32 2, i32 1 + %s2 = select i1 %y, i32 2, i32 1 + %and = and i32 %s1, %s2 + %icmp = icmp eq i32 %and, 0 + ret i1 %icmp +} + +define i1 @select_and_icmpeq_i32_commuted2(i1 %x, i1 %y) { +; CHECK-LABEL: @select_and_icmpeq_i32_commuted2( +; CHECK-NEXT: [[S1:%.*]] = select i1 [[Y:%.*]], i32 4, i32 1 +; CHECK-NEXT: [[S2:%.*]] = select i1 [[X:%.*]], i32 4, i32 1 +; CHECK-NEXT: [[AND:%.*]] = and i32 [[S2]], [[S1]] +; CHECK-NEXT: [[ICMP:%.*]] = icmp eq i32 [[AND]], 0 +; CHECK-NEXT: ret i1 [[ICMP]] +; + %s1 = select i1 %y, i32 4, i32 1 + %s2 = select i1 %x, i32 4, i32 1 + %and = and i32 %s2, %s1 + %icmp = icmp eq i32 %and, 0 + ret i1 %icmp +} + +define i1 @select_and_icmpeq_i32_commuted3(i1 %x, i1 %y) { +; CHECK-LABEL: @select_and_icmpeq_i32_commuted3( +; CHECK-NEXT: [[S1:%.*]] = select i1 [[Y:%.*]], i32 3, i32 12 +; CHECK-NEXT: [[S2:%.*]] = select i1 [[X:%.*]], i32 3, i32 12 +; CHECK-NEXT: [[AND:%.*]] = and i32 [[S1]], [[S2]] +; CHECK-NEXT: [[ICMP:%.*]] = icmp eq i32 [[AND]], 0 +; CHECK-NEXT: ret i1 [[ICMP]] +; + %s1 = select i1 %y, i32 3, i32 12 + %s2 = select i1 %x, i32 3, i32 12 + %and = and i32 %s1, %s2 + %icmp = icmp eq i32 %and, 0 + ret i1 %icmp +} + +define i1 @select_and_icmpeq_i32_commuted4(i1 %x, i1 %y) { +; CHECK-LABEL: @select_and_icmpeq_i32_commuted4( +; CHECK-NEXT: [[S1:%.*]] = select i1 [[Y:%.*]], i32 3, i32 16 +; CHECK-NEXT: [[S2:%.*]] = select i1 [[X:%.*]], i32 3, i32 16 +; CHECK-NEXT: [[AND:%.*]] = and i32 [[S2]], [[S1]] +; CHECK-NEXT: [[ICMP:%.*]] = icmp eq i32 [[AND]], 0 +; CHECK-NEXT: ret i1 [[ICMP]] +; + %s1 = select i1 %y, i32 3, i32 16 + %s2 = select i1 %x, i32 3, i32 16 + %and = and i32 %s2, %s1 + %icmp = icmp eq i32 %and, 0 + ret i1 %icmp +} + +define i1 @select_and_icmpeq_i9(i1 %x, i1 %y) { +; CHECK-LABEL: @select_and_icmpeq_i9( +; CHECK-NEXT: [[S1:%.*]] = select i1 [[Y:%.*]], i9 3, i9 16 +; CHECK-NEXT: [[S2:%.*]] = select i1 [[X:%.*]], i9 3, i9 16 +; CHECK-NEXT: [[AND:%.*]] = and i9 [[S2]], [[S1]] +; CHECK-NEXT: [[ICMP:%.*]] = icmp eq i9 [[AND]], 0 +; CHECK-NEXT: ret i1 [[ICMP]] +; + %s1 = select i1 %y, i9 3, i9 16 + %s2 = select i1 %x, i9 3, i9 16 + %and = and i9 %s2, %s1 + %icmp = icmp eq i9 %and, 0 + ret i1 %icmp +} + +define <5 x i1> @select_and_icmpeq_i1vec(<5 x i1> %x, <5 x i1> %y) { +; CHECK-LABEL: @select_and_icmpeq_i1vec( +; CHECK-NEXT: [[S1:%.*]] = select <5 x i1> [[Y:%.*]], <5 x i32> , <5 x i32> +; CHECK-NEXT: [[S2:%.*]] = select <5 x i1> [[X:%.*]], <5 x i32> , <5 x i32> +; CHECK-NEXT: [[AND:%.*]] = and <5 x i32> [[S2]], [[S1]] +; CHECK-NEXT: [[ICMP:%.*]] = icmp eq <5 x i32> [[AND]], zeroinitializer +; CHECK-NEXT: ret <5 x i1> [[ICMP]] +; + %s1 = select <5 x i1> %y, <5 x i32> , <5 x i32> + %s2 = select <5 x i1> %x, <5 x i32> , <5 x i32> + %and = and <5 x i32> %s2, %s1 + %icmp = icmp eq <5 x i32> %and, + ret <5 x i1> %icmp +} + +define i1 @select_and_icmpeq_i32_multiuse_select1(i1 %x, i1 %y) { +; CHECK-LABEL: @select_and_icmpeq_i32_multiuse_select1( +; CHECK-NEXT: [[S1:%.*]] = select i1 [[Y:%.*]], i32 4, i32 1 +; CHECK-NEXT: call void @use32(i32 [[S1]]) +; CHECK-NEXT: [[S2:%.*]] = select i1 [[X:%.*]], i32 4, i32 1 +; CHECK-NEXT: [[AND:%.*]] = and i32 [[S2]], [[S1]] +; CHECK-NEXT: [[ICMP:%.*]] = icmp eq i32 [[AND]], 0 +; CHECK-NEXT: ret i1 [[ICMP]] +; + %s1 = select i1 %y, i32 4, i32 1 + call void @use32(i32 %s1) ; extra use of first select + %s2 = select i1 %x, i32 4, i32 1 + %and = and i32 %s2, %s1 + %icmp = icmp eq i32 %and, 0 + ret i1 %icmp +} + +define i1 @select_and_icmpeq_i16_multiuse_select2(i1 %x, i1 %y) { +; CHECK-LABEL: @select_and_icmpeq_i16_multiuse_select2( +; CHECK-NEXT: [[S1:%.*]] = select i1 [[Y:%.*]], i16 4, i16 1 +; CHECK-NEXT: [[S2:%.*]] = select i1 [[X:%.*]], i16 4, i16 1 +; CHECK-NEXT: call void @use16(i16 [[S2]]) +; CHECK-NEXT: [[AND:%.*]] = and i16 [[S2]], [[S1]] +; CHECK-NEXT: [[ICMP:%.*]] = icmp eq i16 [[AND]], 0 +; CHECK-NEXT: ret i1 [[ICMP]] +; + %s1 = select i1 %y, i16 4, i16 1 + %s2 = select i1 %x, i16 4, i16 1 + call void @use16(i16 %s2) ; extra use of second select + %and = and i16 %s2, %s1 + %icmp = icmp eq i16 %and, 0 + ret i1 %icmp +} + +define i1 @select_and_icmpeq_i3_multiuse_and(i1 %x, i1 %y) { +; CHECK-LABEL: @select_and_icmpeq_i3_multiuse_and( +; CHECK-NEXT: [[S1:%.*]] = select i1 [[Y:%.*]], i3 1, i3 2 +; CHECK-NEXT: [[S2:%.*]] = select i1 [[X:%.*]], i3 1, i3 2 +; CHECK-NEXT: [[AND:%.*]] = and i3 [[S2]], [[S1]] +; CHECK-NEXT: call void @use3(i3 [[AND]]) +; CHECK-NEXT: [[ICMP:%.*]] = icmp eq i3 [[AND]], 0 +; CHECK-NEXT: ret i1 [[ICMP]] +; + %s1 = select i1 %y, i3 1, i3 2 + %s2 = select i1 %x, i3 1, i3 2 + %and = and i3 %s2, %s1 + call void @use3(i3 %and) ; extra use of and + %icmp = icmp eq i3 %and, 0 + ret i1 %icmp +} + +define i1 @select_and_icmpeq_i7_multiuse_all(i1 %x, i1 %y) { +; CHECK-LABEL: @select_and_icmpeq_i7_multiuse_all( +; CHECK-NEXT: [[S1:%.*]] = select i1 [[Y:%.*]], i7 1, i7 2 +; CHECK-NEXT: [[S2:%.*]] = select i1 [[X:%.*]], i7 1, i7 2 +; CHECK-NEXT: [[AND:%.*]] = and i7 [[S2]], [[S1]] +; CHECK-NEXT: call void @use7(i7 [[S1]]) +; CHECK-NEXT: call void @use7(i7 [[S2]]) +; CHECK-NEXT: call void @use7(i7 [[AND]]) +; CHECK-NEXT: [[ICMP:%.*]] = icmp eq i7 [[AND]], 0 +; CHECK-NEXT: ret i1 [[ICMP]] +; + %s1 = select i1 %y, i7 1, i7 2 + %s2 = select i1 %x, i7 1, i7 2 + %and = and i7 %s2, %s1 + call void @use7(i7 %s1) ; extra use of first select + call void @use7(i7 %s2) ; extra use of second select + call void @use7(i7 %and) ; extra use of and + %icmp = icmp eq i7 %and, 0 + ret i1 %icmp +}