diff options
Diffstat (limited to 'test/Transforms/InstCombine')
30 files changed, 1894 insertions, 40 deletions
diff --git a/test/Transforms/InstCombine/2010-03-03-ExtElim.ll b/test/Transforms/InstCombine/2010-03-03-ExtElim.ll index b1384ec..e0def99 100644 --- a/test/Transforms/InstCombine/2010-03-03-ExtElim.ll +++ b/test/Transforms/InstCombine/2010-03-03-ExtElim.ll @@ -22,11 +22,11 @@ define i1 @PR6486() nounwind { define i1 @PR16462_1() nounwind { ; CHECK-LABEL: @PR16462_1( ret i1 icmp sgt (i32 sext (i16 trunc (i32 select (i1 icmp eq (i32* getelementptr inbounds ([1 x i32]* @a, i32 0, i32 0), i32* @d), i32 0, i32 1) to i16) to i32), i32 65535) -; CHECK: ret i1 icmp sgt (i32 sext (i16 trunc (i32 select (i1 icmp eq (i32* getelementptr inbounds ([1 x i32]* @a, i32 0, i32 0), i32* @d), i32 0, i32 1) to i16) to i32), i32 65535) +; CHECK: ret i1 false } define i1 @PR16462_2() nounwind { ; CHECK-LABEL: @PR16462_2( ret i1 icmp sgt (i32 sext (i16 trunc (i32 select (i1 icmp eq (i32* getelementptr inbounds ([1 x i32]* @a, i32 0, i32 0), i32* @d), i32 0, i32 1) to i16) to i32), i32 42) -; CHECK: ret i1 icmp sgt (i16 trunc (i32 select (i1 icmp eq (i32* getelementptr inbounds ([1 x i32]* @a, i32 0, i32 0), i32* @d), i32 0, i32 1) to i16), i16 42) +; CHECK: ret i1 false } diff --git a/test/Transforms/InstCombine/2012-07-30-addrsp-bitcast.ll b/test/Transforms/InstCombine/2012-07-30-addrsp-bitcast.ll index 4d185bf..ac9c555 100644 --- a/test/Transforms/InstCombine/2012-07-30-addrsp-bitcast.ll +++ b/test/Transforms/InstCombine/2012-07-30-addrsp-bitcast.ll @@ -1,7 +1,7 @@ ; RUN: opt < %s -instcombine -S | FileCheck %s ; CHECK: addrspacecast -@base = internal addrspace(3) unnamed_addr global [16 x i32] zeroinitializer, align 16 +@base = internal unnamed_addr addrspace(3) global [16 x i32] zeroinitializer, align 16 declare void @foo(i32*) define void @test() nounwind { diff --git a/test/Transforms/InstCombine/AddOverFlow.ll b/test/Transforms/InstCombine/AddOverFlow.ll new file mode 100644 index 0000000..8f3d429 --- /dev/null +++ b/test/Transforms/InstCombine/AddOverFlow.ll @@ -0,0 +1,118 @@ +; RUN: opt < %s -instcombine -S | FileCheck %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +; CHECK-LABEL: @oppositesign +; CHECK: add nsw i16 %a, %b +define i16 @oppositesign(i16 %x, i16 %y) { +; %a is negative, %b is positive + %a = or i16 %x, 32768 + %b = and i16 %y, 32767 + %c = add i16 %a, %b + ret i16 %c +} + +define i16 @zero_sign_bit(i16 %a) { +; CHECK-LABEL: @zero_sign_bit( +; CHECK-NEXT: and +; CHECK-NEXT: add nuw +; CHECK-NEXT: ret + %1 = and i16 %a, 32767 + %2 = add i16 %1, 512 + ret i16 %2 +} + +define i16 @zero_sign_bit2(i16 %a, i16 %b) { +; CHECK-LABEL: @zero_sign_bit2( +; CHECK-NEXT: and +; CHECK-NEXT: and +; CHECK-NEXT: add nuw +; CHECK-NEXT: ret + %1 = and i16 %a, 32767 + %2 = and i16 %b, 32767 + %3 = add i16 %1, %2 + ret i16 %3 +} + +declare i16 @bounded(i16 %input); +declare i32 @__gxx_personality_v0(...); +!0 = metadata !{i16 0, i16 32768} ; [0, 32767] +!1 = metadata !{i16 0, i16 32769} ; [0, 32768] + +define i16 @add_bounded_values(i16 %a, i16 %b) { +; CHECK-LABEL: @add_bounded_values( +entry: + %c = call i16 @bounded(i16 %a), !range !0 + %d = invoke i16 @bounded(i16 %b) to label %cont unwind label %lpad, !range !0 +cont: +; %c and %d are in [0, 32767]. Therefore, %c + %d doesn't unsigned overflow. + %e = add i16 %c, %d +; CHECK: add nuw i16 %c, %d + ret i16 %e +lpad: + %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + filter [0 x i8*] zeroinitializer + ret i16 42 +} + +define i16 @add_bounded_values_2(i16 %a, i16 %b) { +; CHECK-LABEL: @add_bounded_values_2( +entry: + %c = call i16 @bounded(i16 %a), !range !1 + %d = invoke i16 @bounded(i16 %b) to label %cont unwind label %lpad, !range !1 +cont: +; Similar to add_bounded_values, but %c and %d are in [0, 32768]. Therefore, +; %c + %d may unsigned overflow and we cannot add NUW. + %e = add i16 %c, %d +; CHECK: add i16 %c, %d + ret i16 %e +lpad: + %0 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + filter [0 x i8*] zeroinitializer + ret i16 42 +} + +; CHECK-LABEL: @ripple_nsw1 +; CHECK: add nsw i16 %a, %b +define i16 @ripple_nsw1(i16 %x, i16 %y) { +; %a has at most one bit set + %a = and i16 %y, 1 + +; %b has a 0 bit other than the sign bit + %b = and i16 %x, 49151 + + %c = add i16 %a, %b + ret i16 %c +} + +; Like the previous test, but flip %a and %b +; CHECK-LABEL: @ripple_nsw2 +; CHECK: add nsw i16 %b, %a +define i16 @ripple_nsw2(i16 %x, i16 %y) { + %a = and i16 %y, 1 + %b = and i16 %x, 49151 + %c = add i16 %b, %a + ret i16 %c +} + +; CHECK-LABEL: @ripple_no_nsw1 +; CHECK: add i32 %a, %x +define i32 @ripple_no_nsw1(i32 %x, i32 %y) { +; We know nothing about %x + %a = and i32 %y, 1 + %b = add i32 %a, %x + ret i32 %b +} + +; CHECK-LABEL: @ripple_no_nsw2 +; CHECK: add nuw i16 %a, %b +define i16 @ripple_no_nsw2(i16 %x, i16 %y) { +; %a has at most one bit set + %a = and i16 %y, 1 + +; %b has a 0 bit, but it is the sign bit + %b = and i16 %x, 32767 + + %c = add i16 %a, %b + ret i16 %c +} diff --git a/test/Transforms/InstCombine/abs_abs.ll b/test/Transforms/InstCombine/abs_abs.ll new file mode 100644 index 0000000..de10fd1 --- /dev/null +++ b/test/Transforms/InstCombine/abs_abs.ll @@ -0,0 +1,961 @@ +; RUN: opt < %s -instcombine -S | FileCheck %s + +define i32 @abs_abs_x01(i32 %x) { + %cmp = icmp sgt i32 %x, -1 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %x, i32 %sub + %cmp1 = icmp sgt i32 %cond, -1 + %sub16 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16 + ret i32 %cond18 +; CHECK-LABEL: @abs_abs_x01( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, -1 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]] +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @abs_abs_x02(i32 %x) { + %cmp = icmp sgt i32 %x, 0 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %x, i32 %sub + %cmp1 = icmp sgt i32 %cond, -1 + %sub16 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16 + ret i32 %cond18 +; CHECK-LABEL: @abs_abs_x02( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, 0 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]] +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @abs_abs_x03(i32 %x) { + %cmp = icmp slt i32 %x, 0 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %sub, i32 %x + %cmp1 = icmp sgt i32 %cond, -1 + %sub16 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16 + ret i32 %cond18 +; CHECK-LABEL: @abs_abs_x03( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 0 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @abs_abs_x04(i32 %x) { + %cmp = icmp slt i32 %x, 1 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %sub, i32 %x + %cmp1 = icmp sgt i32 %cond, -1 + %sub16 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16 + ret i32 %cond18 +; CHECK-LABEL: @abs_abs_x04( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 1 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @abs_abs_x05(i32 %x) { + %cmp = icmp sgt i32 %x, -1 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %x, i32 %sub + %cmp1 = icmp sgt i32 %cond, 0 + %sub16 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16 + ret i32 %cond18 +; CHECK-LABEL: @abs_abs_x05( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, -1 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]] +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @abs_abs_x06(i32 %x) { + %cmp = icmp sgt i32 %x, 0 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %x, i32 %sub + %cmp1 = icmp sgt i32 %cond, 0 + %sub16 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16 + ret i32 %cond18 +; CHECK-LABEL: @abs_abs_x06( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, 0 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]] +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @abs_abs_x07(i32 %x) { + %cmp = icmp slt i32 %x, 0 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %sub, i32 %x + %cmp1 = icmp sgt i32 %cond, 0 + %sub16 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16 + ret i32 %cond18 +; CHECK-LABEL: @abs_abs_x07( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 0 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @abs_abs_x08(i32 %x) { + %cmp = icmp slt i32 %x, 1 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %sub, i32 %x + %cmp1 = icmp sgt i32 %cond, 0 + %sub16 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16 + ret i32 %cond18 +; CHECK-LABEL: @abs_abs_x08( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 1 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @abs_abs_x09(i32 %x) { + %cmp = icmp sgt i32 %x, -1 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %x, i32 %sub + %cmp1 = icmp slt i32 %cond, 0 + %sub9 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond + ret i32 %cond18 +; CHECK-LABEL: @abs_abs_x09( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, -1 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]] +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @abs_abs_x10(i32 %x) { + %cmp = icmp sgt i32 %x, 0 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %x, i32 %sub + %cmp1 = icmp slt i32 %cond, 0 + %sub9 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond + ret i32 %cond18 +; CHECK-LABEL: @abs_abs_x10( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, 0 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]] +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @abs_abs_x11(i32 %x) { + %cmp = icmp slt i32 %x, 0 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %sub, i32 %x + %cmp1 = icmp slt i32 %cond, 0 + %sub9 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond + ret i32 %cond18 +; CHECK-LABEL: @abs_abs_x11( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 0 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @abs_abs_x12(i32 %x) { + %cmp = icmp slt i32 %x, 1 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %sub, i32 %x + %cmp1 = icmp slt i32 %cond, 0 + %sub9 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond + ret i32 %cond18 +; CHECK-LABEL: @abs_abs_x12( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 1 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @abs_abs_x13(i32 %x) { + %cmp = icmp sgt i32 %x, -1 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %x, i32 %sub + %cmp1 = icmp slt i32 %cond, 1 + %sub9 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond + ret i32 %cond18 +; CHECK-LABEL: @abs_abs_x13( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, -1 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]] +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @abs_abs_x14(i32 %x) { + %cmp = icmp sgt i32 %x, 0 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %x, i32 %sub + %cmp1 = icmp slt i32 %cond, 1 + %sub9 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond + ret i32 %cond18 +; CHECK-LABEL: @abs_abs_x14( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, 0 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]] +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @abs_abs_x15(i32 %x) { + %cmp = icmp slt i32 %x, 0 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %sub, i32 %x + %cmp1 = icmp slt i32 %cond, 1 + %sub9 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond + ret i32 %cond18 +; CHECK-LABEL: @abs_abs_x15( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 0 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @abs_abs_x16(i32 %x) { + %cmp = icmp slt i32 %x, 1 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %sub, i32 %x + %cmp1 = icmp slt i32 %cond, 1 + %sub9 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond + ret i32 %cond18 +; CHECK-LABEL: @abs_abs_x16( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 1 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @nabs_nabs_x01(i32 %x) { + %cmp = icmp sgt i32 %x, -1 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %sub, i32 %x + %cmp1 = icmp sgt i32 %cond, -1 + %sub9 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond + ret i32 %cond18 +; CHECK-LABEL: @nabs_nabs_x01( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, -1 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @nabs_nabs_x02(i32 %x) { + %cmp = icmp sgt i32 %x, 0 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %sub, i32 %x + %cmp1 = icmp sgt i32 %cond, -1 + %sub9 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond + ret i32 %cond18 +; CHECK-LABEL: @nabs_nabs_x02( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, 0 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @nabs_nabs_x03(i32 %x) { + %cmp = icmp slt i32 %x, 0 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %x, i32 %sub + %cmp1 = icmp sgt i32 %cond, -1 + %sub9 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond + ret i32 %cond18 +; CHECK-LABEL: @nabs_nabs_x03( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 0 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]] +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @nabs_nabs_x04(i32 %x) { + %cmp = icmp slt i32 %x, 1 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %x, i32 %sub + %cmp1 = icmp sgt i32 %cond, -1 + %sub9 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond + ret i32 %cond18 +; CHECK-LABEL: @nabs_nabs_x04( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 1 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]] +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @nabs_nabs_x05(i32 %x) { + %cmp = icmp sgt i32 %x, -1 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %sub, i32 %x + %cmp1 = icmp sgt i32 %cond, 0 + %sub9 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond + ret i32 %cond18 +; CHECK-LABEL: @nabs_nabs_x05( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, -1 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @nabs_nabs_x06(i32 %x) { + %cmp = icmp sgt i32 %x, 0 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %sub, i32 %x + %cmp1 = icmp sgt i32 %cond, 0 + %sub9 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond + ret i32 %cond18 +; CHECK-LABEL: @nabs_nabs_x06( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, 0 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @nabs_nabs_x07(i32 %x) { + %cmp = icmp slt i32 %x, 0 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %x, i32 %sub + %cmp1 = icmp sgt i32 %cond, 0 + %sub9 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond + ret i32 %cond18 +; CHECK-LABEL: @nabs_nabs_x07( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 0 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]] +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @nabs_nabs_x08(i32 %x) { + %cmp = icmp slt i32 %x, 1 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %x, i32 %sub + %cmp1 = icmp sgt i32 %cond, 0 + %sub9 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond + ret i32 %cond18 +; CHECK-LABEL: @nabs_nabs_x08( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 1 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]] +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @nabs_nabs_x09(i32 %x) { + %cmp = icmp sgt i32 %x, -1 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %sub, i32 %x + %cmp1 = icmp slt i32 %cond, 0 + %sub16 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16 + ret i32 %cond18 +; CHECK-LABEL: @nabs_nabs_x09( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, -1 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @nabs_nabs_x10(i32 %x) { + %cmp = icmp sgt i32 %x, 0 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %sub, i32 %x + %cmp1 = icmp slt i32 %cond, 0 + %sub16 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16 + ret i32 %cond18 +; CHECK-LABEL: @nabs_nabs_x10( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, 0 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @nabs_nabs_x11(i32 %x) { + %cmp = icmp slt i32 %x, 0 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %x, i32 %sub + %cmp1 = icmp slt i32 %cond, 0 + %sub16 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16 + ret i32 %cond18 +; CHECK-LABEL: @nabs_nabs_x11( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 0 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]] +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @nabs_nabs_x12(i32 %x) { + %cmp = icmp slt i32 %x, 1 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %x, i32 %sub + %cmp1 = icmp slt i32 %cond, 0 + %sub16 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16 + ret i32 %cond18 +; CHECK-LABEL: @nabs_nabs_x12( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 1 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]] +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @nabs_nabs_x13(i32 %x) { + %cmp = icmp sgt i32 %x, -1 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %sub, i32 %x + %cmp1 = icmp slt i32 %cond, 1 + %sub16 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16 + ret i32 %cond18 +; CHECK-LABEL: @nabs_nabs_x13( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, -1 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @nabs_nabs_x14(i32 %x) { + %cmp = icmp sgt i32 %x, 0 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %sub, i32 %x + %cmp1 = icmp slt i32 %cond, 1 + %sub16 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16 + ret i32 %cond18 +; CHECK-LABEL: @nabs_nabs_x14( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, 0 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @nabs_nabs_x15(i32 %x) { + %cmp = icmp slt i32 %x, 0 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %x, i32 %sub + %cmp1 = icmp slt i32 %cond, 1 + %sub16 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16 + ret i32 %cond18 +; CHECK-LABEL: @nabs_nabs_x15( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 0 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]] +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @nabs_nabs_x16(i32 %x) { + %cmp = icmp slt i32 %x, 1 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %x, i32 %sub + %cmp1 = icmp slt i32 %cond, 1 + %sub16 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16 + ret i32 %cond18 +; CHECK-LABEL: @nabs_nabs_x16( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 1 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]] +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @abs_nabs_x01(i32 %x) { + %cmp = icmp sgt i32 %x, -1 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %sub, i32 %x + %cmp1 = icmp sgt i32 %cond, -1 + %sub16 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16 + ret i32 %cond18 +; CHECK-LABEL: @abs_nabs_x01( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, -1 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]] +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @abs_nabs_x02(i32 %x) { + %cmp = icmp sgt i32 %x, 0 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %sub, i32 %x + %cmp1 = icmp sgt i32 %cond, -1 + %sub16 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16 + ret i32 %cond18 +; CHECK-LABEL: @abs_nabs_x02( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, 0 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]] +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @abs_nabs_x03(i32 %x) { + %cmp = icmp slt i32 %x, 0 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %x, i32 %sub + %cmp1 = icmp sgt i32 %cond, -1 + %sub16 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16 + ret i32 %cond18 +; CHECK-LABEL: @abs_nabs_x03( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 0 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @abs_nabs_x04(i32 %x) { + %cmp = icmp slt i32 %x, 1 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %x, i32 %sub + %cmp1 = icmp sgt i32 %cond, -1 + %sub16 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16 + ret i32 %cond18 +; CHECK-LABEL: @abs_nabs_x04( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 1 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @abs_nabs_x05(i32 %x) { + %cmp = icmp sgt i32 %x, -1 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %sub, i32 %x + %cmp1 = icmp sgt i32 %cond, 0 + %sub16 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16 + ret i32 %cond18 +; CHECK-LABEL: @abs_nabs_x05( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, -1 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]] +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @abs_nabs_x06(i32 %x) { + %cmp = icmp sgt i32 %x, 0 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %sub, i32 %x + %cmp1 = icmp sgt i32 %cond, 0 + %sub16 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16 + ret i32 %cond18 +; CHECK-LABEL: @abs_nabs_x06( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, 0 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]] +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @abs_nabs_x07(i32 %x) { + %cmp = icmp slt i32 %x, 0 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %x, i32 %sub + %cmp1 = icmp sgt i32 %cond, 0 + %sub16 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16 + ret i32 %cond18 +; CHECK-LABEL: @abs_nabs_x07( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 0 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @abs_nabs_x08(i32 %x) { + %cmp = icmp slt i32 %x, 1 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %x, i32 %sub + %cmp1 = icmp sgt i32 %cond, 0 + %sub16 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16 + ret i32 %cond18 +; CHECK-LABEL: @abs_nabs_x08( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 1 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @abs_nabs_x09(i32 %x) { + %cmp = icmp sgt i32 %x, -1 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %sub, i32 %x + %cmp1 = icmp slt i32 %cond, 0 + %sub9 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond + ret i32 %cond18 +; CHECK-LABEL: @abs_nabs_x09( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, -1 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]] +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @abs_nabs_x10(i32 %x) { + %cmp = icmp sgt i32 %x, 0 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %sub, i32 %x + %cmp1 = icmp slt i32 %cond, 0 + %sub9 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond + ret i32 %cond18 +; CHECK-LABEL: @abs_nabs_x10( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, 0 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]] +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @abs_nabs_x11(i32 %x) { + %cmp = icmp slt i32 %x, 0 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %x, i32 %sub + %cmp1 = icmp slt i32 %cond, 0 + %sub9 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond + ret i32 %cond18 +; CHECK-LABEL: @abs_nabs_x11( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 0 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @abs_nabs_x12(i32 %x) { + %cmp = icmp slt i32 %x, 1 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %x, i32 %sub + %cmp1 = icmp slt i32 %cond, 0 + %sub9 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond + ret i32 %cond18 +; CHECK-LABEL: @abs_nabs_x12( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 1 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @abs_nabs_x13(i32 %x) { + %cmp = icmp sgt i32 %x, -1 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %sub, i32 %x + %cmp1 = icmp slt i32 %cond, 1 + %sub9 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond + ret i32 %cond18 +; CHECK-LABEL: @abs_nabs_x13( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, -1 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]] +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @abs_nabs_x14(i32 %x) { + %cmp = icmp sgt i32 %x, 0 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %sub, i32 %x + %cmp1 = icmp slt i32 %cond, 1 + %sub9 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond + ret i32 %cond18 +; CHECK-LABEL: @abs_nabs_x14( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, 0 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]] +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @abs_nabs_x15(i32 %x) { + %cmp = icmp slt i32 %x, 0 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %x, i32 %sub + %cmp1 = icmp slt i32 %cond, 1 + %sub9 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond + ret i32 %cond18 +; CHECK-LABEL: @abs_nabs_x15( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 0 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @abs_nabs_x16(i32 %x) { + %cmp = icmp slt i32 %x, 1 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %x, i32 %sub + %cmp1 = icmp slt i32 %cond, 1 + %sub9 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond + ret i32 %cond18 +; CHECK-LABEL: @abs_nabs_x16( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 1 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @nabs_abs_x01(i32 %x) { + %cmp = icmp sgt i32 %x, -1 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %x, i32 %sub + %cmp1 = icmp sgt i32 %cond, -1 + %sub9 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond + ret i32 %cond18 +; CHECK-LABEL: @nabs_abs_x01( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, -1 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @nabs_abs_x02(i32 %x) { + %cmp = icmp sgt i32 %x, 0 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %x, i32 %sub + %cmp1 = icmp sgt i32 %cond, -1 + %sub9 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond + ret i32 %cond18 +; CHECK-LABEL: @nabs_abs_x02( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, 0 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @nabs_abs_x03(i32 %x) { + %cmp = icmp slt i32 %x, 0 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %sub, i32 %x + %cmp1 = icmp sgt i32 %cond, -1 + %sub9 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond + ret i32 %cond18 +; CHECK-LABEL: @nabs_abs_x03( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 0 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]] +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @nabs_abs_x04(i32 %x) { + %cmp = icmp slt i32 %x, 1 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %sub, i32 %x + %cmp1 = icmp sgt i32 %cond, -1 + %sub9 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond + ret i32 %cond18 +; CHECK-LABEL: @nabs_abs_x04( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 1 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]] +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @nabs_abs_x05(i32 %x) { + %cmp = icmp sgt i32 %x, -1 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %x, i32 %sub + %cmp1 = icmp sgt i32 %cond, 0 + %sub9 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond + ret i32 %cond18 +; CHECK-LABEL: @nabs_abs_x05( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, -1 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @nabs_abs_x06(i32 %x) { + %cmp = icmp sgt i32 %x, 0 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %x, i32 %sub + %cmp1 = icmp sgt i32 %cond, 0 + %sub9 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond + ret i32 %cond18 +; CHECK-LABEL: @nabs_abs_x06( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, 0 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @nabs_abs_x07(i32 %x) { + %cmp = icmp slt i32 %x, 0 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %sub, i32 %x + %cmp1 = icmp sgt i32 %cond, 0 + %sub9 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond + ret i32 %cond18 +; CHECK-LABEL: @nabs_abs_x07( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 0 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]] +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @nabs_abs_x08(i32 %x) { + %cmp = icmp slt i32 %x, 1 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %sub, i32 %x + %cmp1 = icmp sgt i32 %cond, 0 + %sub9 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %sub9, i32 %cond + ret i32 %cond18 +; CHECK-LABEL: @nabs_abs_x08( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 1 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]] +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @nabs_abs_x09(i32 %x) { + %cmp = icmp sgt i32 %x, -1 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %x, i32 %sub + %cmp1 = icmp slt i32 %cond, 0 + %sub16 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16 + ret i32 %cond18 +; CHECK-LABEL: @nabs_abs_x09( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, -1 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @nabs_abs_x10(i32 %x) { + %cmp = icmp sgt i32 %x, 0 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %x, i32 %sub + %cmp1 = icmp slt i32 %cond, 0 + %sub16 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16 + ret i32 %cond18 +; CHECK-LABEL: @nabs_abs_x10( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, 0 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @nabs_abs_x11(i32 %x) { + %cmp = icmp slt i32 %x, 0 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %sub, i32 %x + %cmp1 = icmp slt i32 %cond, 0 + %sub16 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16 + ret i32 %cond18 +; CHECK-LABEL: @nabs_abs_x11( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 0 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]] +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @nabs_abs_x12(i32 %x) { + %cmp = icmp slt i32 %x, 1 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %sub, i32 %x + %cmp1 = icmp slt i32 %cond, 0 + %sub16 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16 + ret i32 %cond18 +; CHECK-LABEL: @nabs_abs_x12( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 1 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]] +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @nabs_abs_x13(i32 %x) { + %cmp = icmp sgt i32 %x, -1 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %x, i32 %sub + %cmp1 = icmp slt i32 %cond, 1 + %sub16 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16 + ret i32 %cond18 +; CHECK-LABEL: @nabs_abs_x13( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, -1 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @nabs_abs_x14(i32 %x) { + %cmp = icmp sgt i32 %x, 0 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %x, i32 %sub + %cmp1 = icmp slt i32 %cond, 1 + %sub16 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16 + ret i32 %cond18 +; CHECK-LABEL: @nabs_abs_x14( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp sgt i32 %x, 0 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[NEG]], i32 %x +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @nabs_abs_x15(i32 %x) { + %cmp = icmp slt i32 %x, 0 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %sub, i32 %x + %cmp1 = icmp slt i32 %cond, 1 + %sub16 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16 + ret i32 %cond18 +; CHECK-LABEL: @nabs_abs_x15( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 0 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]] +; CHECK-NEXT: ret i32 [[SEL]] +} + +define i32 @nabs_abs_x16(i32 %x) { + %cmp = icmp slt i32 %x, 1 + %sub = sub nsw i32 0, %x + %cond = select i1 %cmp, i32 %sub, i32 %x + %cmp1 = icmp slt i32 %cond, 1 + %sub16 = sub nsw i32 0, %cond + %cond18 = select i1 %cmp1, i32 %cond, i32 %sub16 + ret i32 %cond18 +; CHECK-LABEL: @nabs_abs_x16( +; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp slt i32 %x, 1 +; CHECK-NEXT: [[NEG:%[a-z0-9]+]] = sub nsw i32 0, %x +; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 %x, i32 [[NEG]] +; CHECK-NEXT: ret i32 [[SEL]] +}
\ No newline at end of file diff --git a/test/Transforms/InstCombine/add-shrink.ll b/test/Transforms/InstCombine/add-shrink.ll index 3edb392..67a990f 100644 --- a/test/Transforms/InstCombine/add-shrink.ll +++ b/test/Transforms/InstCombine/add-shrink.ll @@ -1,9 +1,11 @@ -; RUN: opt < %s -instcombine -S | grep "add nsw i32" -; RUN: opt < %s -instcombine -S | grep sext | count 1 - -; Should only have one sext and the add should be i32 instead of i64. +; RUN: opt < %s -instcombine -S | FileCheck %s +; CHECK-LABEL: define i64 @test define i64 @test1(i32 %A) { +; CHECK: %[[ADD:.*]] = add nsw i32 %B, %C +; CHECK: %F = sext i32 %[[ADD]] to i64 +; CHECK: ret i64 %F + %B = ashr i32 %A, 7 ; <i32> [#uses=1] %C = ashr i32 %A, 9 ; <i32> [#uses=1] %D = sext i32 %B to i64 ; <i64> [#uses=1] diff --git a/test/Transforms/InstCombine/add-sitofp.ll b/test/Transforms/InstCombine/add-sitofp.ll index 40edf71..3b5485e 100644 --- a/test/Transforms/InstCombine/add-sitofp.ll +++ b/test/Transforms/InstCombine/add-sitofp.ll @@ -1,4 +1,4 @@ -; RUN: opt < %s -instcombine -S | grep "add nsw i32" +; RUN: opt < %s -instcombine -S | grep "add nuw nsw i32" define double @x(i32 %a, i32 %b) nounwind { %m = lshr i32 %a, 24 diff --git a/test/Transforms/InstCombine/add2.ll b/test/Transforms/InstCombine/add2.ll index 67d560e..d7eac4b 100644 --- a/test/Transforms/InstCombine/add2.ll +++ b/test/Transforms/InstCombine/add2.ll @@ -76,3 +76,240 @@ define <2 x i64> @test8(<2 x i64> %A) { ; CHECK-NEXT: %add = sub <2 x i64> <i64 1, i64 2>, %A ; CHECK-NEXT: ret <2 x i64> %add } + +define i16 @test9(i16 %a) { + %b = mul i16 %a, 2 + %c = mul i16 %a, 32767 + %d = add i16 %b, %c + ret i16 %d +; CHECK-LABEL: @test9( +; CHECK-NEXT: %d = mul i16 %a, -32767 +; CHECK-NEXT: ret i16 %d +} + +; y + (~((x >> 3) & 0x55555555) + 1) -> y - ((x >> 3) & 0x55555555) +define i32 @test10(i32 %x, i32 %y) { + %shr = ashr i32 %x, 3 + %shr.not = or i32 %shr, -1431655766 + %neg = xor i32 %shr.not, 1431655765 + %add = add i32 %y, 1 + %add1 = add i32 %add, %neg + ret i32 %add1 +; CHECK-LABEL: @test10( +; CHECK-NEXT: [[SHR:%[a-z0-9]+]] = ashr i32 %x, 3 +; CHECK-NEXT: [[AND:%[a-z0-9]+]] = and i32 [[SHR]], 1431655765 +; CHECK-NEXT: [[SUB:%[a-z0-9]+]] = sub i32 %y, [[AND]] +; CHECK-NEXT: ret i32 [[SUB]] +} + +; y + (~(x & 0x55555555) + 1) -> y - (x & 0x55555555) +define i32 @test11(i32 %x, i32 %y) { + %x.not = or i32 %x, -1431655766 + %neg = xor i32 %x.not, 1431655765 + %add = add i32 %y, 1 + %add1 = add i32 %add, %neg + ret i32 %add1 +; CHECK-LABEL: @test11( +; CHECK-NEXT: [[AND:%[a-z0-9]+]] = and i32 %x, 1431655765 +; CHECK-NEXT: [[SUB:%[a-z0-9]+]] = sub i32 %y, [[AND]] +; CHECK-NEXT: ret i32 [[SUB]] +} + +; (y + 1) + ~(x & 0x55555555) -> y - (x & 0x55555555) +define i32 @test12(i32 %x, i32 %y) { + %add = add nsw i32 %y, 1 + %x.not = or i32 %x, -1431655766 + %neg = xor i32 %x.not, 1431655765 + %add1 = add nsw i32 %add, %neg + ret i32 %add1 +; CHECK-LABEL: @test12( +; CHECK-NEXT: [[AND:%[a-z0-9]+]] = and i32 %x, 1431655765 +; CHECK-NEXT: [[SUB:%[a-z0-9]+]] = sub i32 %y, [[AND]] +; CHECK-NEXT: ret i32 [[SUB]] +} + +; y + (~(x & 0x55555556) + 1) -> y - (x & 0x55555556) +define i32 @test13(i32 %x, i32 %y) { + %x.not = or i32 %x, -1431655767 + %neg = xor i32 %x.not, 1431655766 + %add = add i32 %y, 1 + %add1 = add i32 %add, %neg + ret i32 %add1 +; CHECK-LABEL: @test13( +; CHECK-NEXT: [[AND:%[a-z0-9]+]] = and i32 %x, 1431655766 +; CHECK-NEXT: [[SUB:%[a-z0-9]+]] = sub i32 %y, [[AND]] +; CHECK-NEXT: ret i32 [[SUB]] +} + +; (y + 1) + ~(x & 0x55555556) -> y - (x & 0x55555556) +define i32 @test14(i32 %x, i32 %y) { + %add = add nsw i32 %y, 1 + %x.not = or i32 %x, -1431655767 + %neg = xor i32 %x.not, 1431655766 + %add1 = add nsw i32 %add, %neg + ret i32 %add1 +; CHECK-LABEL: @test14( +; CHECK-NEXT: [[AND:%[a-z0-9]+]] = and i32 %x, 1431655766 +; CHECK-NEXT: [[SUB:%[a-z0-9]+]] = sub i32 %y, [[AND]] +; CHECK-NEXT: ret i32 [[SUB]] +} + +; y + (~(x | 0x55555556) + 1) -> y - (x | 0x55555556) +define i32 @test15(i32 %x, i32 %y) { + %x.not = and i32 %x, -1431655767 + %neg = xor i32 %x.not, -1431655767 + %add = add i32 %y, 1 + %add1 = add i32 %add, %neg + ret i32 %add1 +; CHECK-LABEL: @test15( +; CHECK-NEXT: [[AND:%[a-z0-9]+]] = or i32 %x, 1431655766 +; CHECK-NEXT: [[SUB:%[a-z0-9]+]] = sub i32 %y, [[AND]] +; CHECK-NEXT: ret i32 [[SUB]] +} + +; (y + 1) + ~(x | 0x55555556) -> y - (x | 0x555555556) +define i32 @test16(i32 %x, i32 %y) { + %add = add nsw i32 %y, 1 + %x.not = and i32 %x, -1431655767 + %neg = xor i32 %x.not, -1431655767 + %add1 = add nsw i32 %add, %neg + ret i32 %add1 +; CHECK-LABEL: @test16( +; CHECK-NEXT: [[AND:%[a-z0-9]+]] = or i32 %x, 1431655766 +; CHECK-NEXT: [[SUB:%[a-z0-9]+]] = sub i32 %y, [[AND]] +; CHECK-NEXT: ret i32 [[SUB]] +} + +; y + (~(x | 0x55555555) + 1) -> y - (x | 0x55555555) +define i32 @test17(i32 %x, i32 %y) { + %x.not = and i32 %x, -1431655766 + %add2 = xor i32 %x.not, -1431655765 + %add1 = add nsw i32 %add2, %y + ret i32 %add1 +; CHECK-LABEL: @test17( +; CHECK-NEXT: [[AND:%[a-z0-9]+]] = or i32 %x, 1431655765 +; CHECK-NEXT: [[SUB:%[a-z0-9]+]] = sub i32 %y, [[AND]] +; CHECK-NEXT: ret i32 [[SUB]] +} + +; (y + 1) + ~(x | 0x55555555) -> y - (x | 0x55555555) +define i32 @test18(i32 %x, i32 %y) { + %add = add nsw i32 %y, 1 + %x.not = and i32 %x, -1431655766 + %neg = xor i32 %x.not, -1431655766 + %add1 = add nsw i32 %add, %neg + ret i32 %add1 +; CHECK-LABEL: @test18( +; CHECK-NEXT: [[AND:%[a-z0-9]+]] = or i32 %x, 1431655765 +; CHECK-NEXT: [[SUB:%[a-z0-9]+]] = sub i32 %y, [[AND]] +; CHECK-NEXT: ret i32 [[SUB]] +} + +define i16 @add_nsw_mul_nsw(i16 %x) { + %add1 = add nsw i16 %x, %x + %add2 = add nsw i16 %add1, %x + ret i16 %add2 +; CHECK-LABEL: @add_nsw_mul_nsw( +; CHECK-NEXT: %add2 = mul nsw i16 %x, 3 +; CHECK-NEXT: ret i16 %add2 +} + +define i16 @mul_add_to_mul_1(i16 %x) { + %mul1 = mul nsw i16 %x, 8 + %add2 = add nsw i16 %x, %mul1 + ret i16 %add2 +; CHECK-LABEL: @mul_add_to_mul_1( +; CHECK-NEXT: %add2 = mul nsw i16 %x, 9 +; CHECK-NEXT: ret i16 %add2 +} + +define i16 @mul_add_to_mul_2(i16 %x) { + %mul1 = mul nsw i16 %x, 8 + %add2 = add nsw i16 %mul1, %x + ret i16 %add2 +; CHECK-LABEL: @mul_add_to_mul_2( +; CHECK-NEXT: %add2 = mul nsw i16 %x, 9 +; CHECK-NEXT: ret i16 %add2 +} + +define i16 @mul_add_to_mul_3(i16 %a) { + %mul1 = mul i16 %a, 2 + %mul2 = mul i16 %a, 3 + %add = add nsw i16 %mul1, %mul2 + ret i16 %add +; CHECK-LABEL: @mul_add_to_mul_3( +; CHECK-NEXT: %add = mul i16 %a, 5 +; CHECK-NEXT: ret i16 %add +} + +define i16 @mul_add_to_mul_4(i16 %a) { + %mul1 = mul nsw i16 %a, 2 + %mul2 = mul nsw i16 %a, 7 + %add = add nsw i16 %mul1, %mul2 + ret i16 %add +; CHECK-LABEL: @mul_add_to_mul_4( +; CHECK-NEXT: %add = mul nsw i16 %a, 9 +; CHECK-NEXT: ret i16 %add +} + +define i16 @mul_add_to_mul_5(i16 %a) { + %mul1 = mul nsw i16 %a, 3 + %mul2 = mul nsw i16 %a, 7 + %add = add nsw i16 %mul1, %mul2 + ret i16 %add +; CHECK-LABEL: @mul_add_to_mul_5( +; CHECK-NEXT: %add = mul nsw i16 %a, 10 +; CHECK-NEXT: ret i16 %add +} + +define i32 @mul_add_to_mul_6(i32 %x, i32 %y) { + %mul1 = mul nsw i32 %x, %y + %mul2 = mul nsw i32 %mul1, 5 + %add = add nsw i32 %mul1, %mul2 + ret i32 %add +; CHECK-LABEL: @mul_add_to_mul_6( +; CHECK-NEXT: %mul1 = mul nsw i32 %x, %y +; CHECK-NEXT: %add = mul nsw i32 %mul1, 6 +; CHECK-NEXT: ret i32 %add +} + +; This test and the next test verify that when a range metadata is attached to +; llvm.cttz, ValueTracking correctly intersects the range specified by the +; metadata and the range implied by the intrinsic. +; +; In this test, the range specified by the metadata is more strict. Therefore, +; ValueTracking uses that range. +define i16 @add_cttz(i16 %a) { +; CHECK-LABEL: @add_cttz( + ; llvm.cttz.i16(..., /*is_zero_undefined=*/true) implies the value returned + ; is in [0, 16). The range metadata indicates the value returned is in [0, 8). + ; Intersecting these ranges, we know the value returned is in [0, 8). + ; Therefore, InstCombine will transform + ; add %cttz, 1111 1111 1111 1000 ; decimal -8 + ; to + ; or %cttz, 1111 1111 1111 1000 + %cttz = call i16 @llvm.cttz.i16(i16 %a, i1 true), !range !0 + %b = add i16 %cttz, -8 +; CHECK: or i16 %cttz, -8 + ret i16 %b +} +declare i16 @llvm.cttz.i16(i16, i1) +!0 = metadata !{i16 0, i16 8} + +; Similar to @add_cttz, but in this test, the range implied by the +; intrinsic is more strict. Therefore, ValueTracking uses that range. +define i16 @add_cttz_2(i16 %a) { +; CHECK-LABEL: @add_cttz_2( + ; llvm.cttz.i16(..., /*is_zero_undefined=*/true) implies the value returned + ; is in [0, 16). The range metadata indicates the value returned is in + ; [0, 32). Intersecting these ranges, we know the value returned is in + ; [0, 16). Therefore, InstCombine will transform + ; add %cttz, 1111 1111 1111 0000 ; decimal -16 + ; to + ; or %cttz, 1111 1111 1111 0000 + %cttz = call i16 @llvm.cttz.i16(i16 %a, i1 true), !range !1 + %b = add i16 %cttz, -16 +; CHECK: or i16 %cttz, -16 + ret i16 %b +} +!1 = metadata !{i16 0, i16 32} diff --git a/test/Transforms/InstCombine/addrspacecast.ll b/test/Transforms/InstCombine/addrspacecast.ll index d908b55..c168436 100644 --- a/test/Transforms/InstCombine/addrspacecast.ll +++ b/test/Transforms/InstCombine/addrspacecast.ll @@ -28,13 +28,91 @@ define <4 x i32*> @combine_redundant_addrspacecast_vector(<4 x i32 addrspace(1)* define float* @combine_redundant_addrspacecast_types(i32 addrspace(1)* %x) nounwind { ; CHECK-LABEL: @combine_redundant_addrspacecast_types( -; CHECK: addrspacecast i32 addrspace(1)* %x to float* +; CHECK-NEXT: bitcast i32 addrspace(1)* %x to float addrspace(1)* +; CHECK-NEXT: addrspacecast float addrspace(1)* %1 to float* ; CHECK-NEXT: ret %y = addrspacecast i32 addrspace(1)* %x to i32 addrspace(3)* %z = addrspacecast i32 addrspace(3)* %y to float* ret float* %z } +define <4 x float*> @combine_redundant_addrspacecast_types_vector(<4 x i32 addrspace(1)*> %x) nounwind { +; CHECK-LABEL: @combine_redundant_addrspacecast_types_vector( +; CHECK-NEXT: bitcast <4 x i32 addrspace(1)*> %x to <4 x float addrspace(1)*> +; CHECK-NEXT: addrspacecast <4 x float addrspace(1)*> %1 to <4 x float*> +; CHECK-NEXT: ret + %y = addrspacecast <4 x i32 addrspace(1)*> %x to <4 x i32 addrspace(3)*> + %z = addrspacecast <4 x i32 addrspace(3)*> %y to <4 x float*> + ret <4 x float*> %z +} + +define float addrspace(2)* @combine_addrspacecast_bitcast_1(i32 addrspace(1)* %x) nounwind { +; CHECK-LABEL: @combine_addrspacecast_bitcast_1( +; CHECK-NEXT: bitcast i32 addrspace(1)* %x to float addrspace(1)* +; CHECK-NEXT: addrspacecast float addrspace(1)* %1 to float addrspace(2)* +; CHECK-NEXT: ret + %y = addrspacecast i32 addrspace(1)* %x to i32 addrspace(2)* + %z = bitcast i32 addrspace(2)* %y to float addrspace(2)* + ret float addrspace(2)* %z +} + +define i32 addrspace(2)* @combine_addrspacecast_bitcast_2(i32 addrspace(1)* %x) nounwind { +; CHECK-LABEL: @combine_addrspacecast_bitcast_2( +; CHECK: addrspacecast i32 addrspace(1)* %x to i32 addrspace(2)* +; CHECK-NEXT: ret + %y = addrspacecast i32 addrspace(1)* %x to float addrspace(2)* + %z = bitcast float addrspace(2)* %y to i32 addrspace(2)* + ret i32 addrspace(2)* %z +} + +define i32 addrspace(2)* @combine_bitcast_addrspacecast_1(i32 addrspace(1)* %x) nounwind { +; CHECK-LABEL: @combine_bitcast_addrspacecast_1( +; CHECK: addrspacecast i32 addrspace(1)* %x to i32 addrspace(2)* +; CHECK-NEXT: ret + %y = bitcast i32 addrspace(1)* %x to i8 addrspace(1)* + %z = addrspacecast i8 addrspace(1)* %y to i32 addrspace(2)* + ret i32 addrspace(2)* %z +} + +define float addrspace(2)* @combine_bitcast_addrspacecast_2(i32 addrspace(1)* %x) nounwind { +; CHECK-LABEL: @combine_bitcast_addrspacecast_2( +; CHECK: bitcast i32 addrspace(1)* %x to float addrspace(1)* +; CHECK: addrspacecast float addrspace(1)* %1 to float addrspace(2)* +; CHECK-NEXT: ret + %y = bitcast i32 addrspace(1)* %x to i8 addrspace(1)* + %z = addrspacecast i8 addrspace(1)* %y to float addrspace(2)* + ret float addrspace(2)* %z +} + +define float addrspace(2)* @combine_addrspacecast_types(i32 addrspace(1)* %x) nounwind { +; CHECK-LABEL: @combine_addrspacecast_types( +; CHECK-NEXT: bitcast i32 addrspace(1)* %x to float addrspace(1)* +; CHECK-NEXT: addrspacecast float addrspace(1)* %1 to float addrspace(2)* +; CHECK-NEXT: ret + %y = addrspacecast i32 addrspace(1)* %x to float addrspace(2)* + ret float addrspace(2)* %y +} + +define <4 x float addrspace(2)*> @combine_addrspacecast_types_vector(<4 x i32 addrspace(1)*> %x) nounwind { +; CHECK-LABEL: @combine_addrspacecast_types_vector( +; CHECK-NEXT: bitcast <4 x i32 addrspace(1)*> %x to <4 x float addrspace(1)*> +; CHECK-NEXT: addrspacecast <4 x float addrspace(1)*> %1 to <4 x float addrspace(2)*> +; CHECK-NEXT: ret + %y = addrspacecast <4 x i32 addrspace(1)*> %x to <4 x float addrspace(2)*> + ret <4 x float addrspace(2)*> %y +} + +define i32 @canonicalize_addrspacecast([16 x i32] addrspace(1)* %arr) { +; CHECK-LABEL: @canonicalize_addrspacecast( +; CHECK-NEXT: getelementptr inbounds [16 x i32] addrspace(1)* %arr, i32 0, i32 0 +; CHECK-NEXT: addrspacecast i32 addrspace(1)* %{{[a-zA-Z0-9]+}} to i32* +; CHECK-NEXT: load i32* +; CHECK-NEXT: ret i32 + %p = addrspacecast [16 x i32] addrspace(1)* %arr to i32* + %v = load i32* %p + ret i32 %v +} + @const_array = addrspace(2) constant [60 x i8] [i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22, i8 2, i8 9, i8 4, i8 22, diff --git a/test/Transforms/InstCombine/align-2d-gep.ll b/test/Transforms/InstCombine/align-2d-gep.ll index 5bca46d..f6a8776 100644 --- a/test/Transforms/InstCombine/align-2d-gep.ll +++ b/test/Transforms/InstCombine/align-2d-gep.ll @@ -31,7 +31,7 @@ bb1: store <2 x double><double 0.0, double 0.0>, <2 x double>* %r, align 8 %indvar.next = add i64 %j, 2 - %exitcond = icmp eq i64 %indvar.next, 557 + %exitcond = icmp eq i64 %indvar.next, 556 br i1 %exitcond, label %bb11, label %bb1 bb11: diff --git a/test/Transforms/InstCombine/bitcast-alias-function.ll b/test/Transforms/InstCombine/bitcast-alias-function.ll index 284960b..a6b56f9 100644 --- a/test/Transforms/InstCombine/bitcast-alias-function.ll +++ b/test/Transforms/InstCombine/bitcast-alias-function.ll @@ -6,46 +6,46 @@ target datalayout = "e-p:32:32:32-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v16:16 ; Cases that should be bitcast ; Test cast between scalars with same bit sizes -@alias_i32_to_f32 = alias float (float), i32 (i32)* @func_i32 +@alias_i32_to_f32 = alias bitcast (i32 (i32)* @func_i32 to float (float)*) ; Test cast between vectors with same number of elements and bit sizes -@alias_v2i32_to_v2f32 = alias <2 x float> (<2 x float>), <2 x i32> (<2 x i32>)* @func_v2i32 +@alias_v2i32_to_v2f32 = alias bitcast (<2 x i32> (<2 x i32>)* @func_v2i32 to <2 x float> (<2 x float>)*) ; Test cast from vector to scalar with same number of bits -@alias_v2f32_to_i64 = alias <2 x float> (<2 x float>), i64 (i64)* @func_i64 +@alias_v2f32_to_i64 = alias bitcast (i64 (i64)* @func_i64 to <2 x float> (<2 x float>)*) ; Test cast from scalar to vector with same number of bits -@alias_i64_to_v2f32 = alias i64 (i64), <2 x float> (<2 x float>)* @func_v2f32 +@alias_i64_to_v2f32 = alias bitcast (<2 x float> (<2 x float>)* @func_v2f32 to i64 (i64)*) ; Test cast between vectors of pointers -@alias_v2i32p_to_v2i64p = alias <2 x i64*> (<2 x i64*>), <2 x i32*> (<2 x i32*>)* @func_v2i32p +@alias_v2i32p_to_v2i64p = alias bitcast (<2 x i32*> (<2 x i32*>)* @func_v2i32p to <2 x i64*> (<2 x i64*>)*) ; Cases that should be invalid and unchanged ; Test cast between scalars with different bit sizes -@alias_i64_to_f32 = alias float (float), i64 (i64)* @func_i64 +@alias_i64_to_f32 = alias bitcast (i64 (i64)* @func_i64 to float (float)*) ; Test cast between vectors with different bit sizes but the ; same number of elements -@alias_v2i64_to_v2f32 = alias <2 x float> (<2 x float>), <2 x i64> (<2 x i64>)* @func_v2i64 +@alias_v2i64_to_v2f32 = alias bitcast (<2 x i64> (<2 x i64>)* @func_v2i64 to <2 x float> (<2 x float>)*) ; Test cast between vectors with same number of bits and different ; numbers of elements -@alias_v2i32_to_v4f32 = alias <4 x float> (<4 x float>), <2 x i32> (<2 x i32>)* @func_v2i32 +@alias_v2i32_to_v4f32 = alias bitcast (<2 x i32> (<2 x i32>)* @func_v2i32 to <4 x float> (<4 x float>)*) ; Test cast between scalar and vector with different number of bits -@alias_i64_to_v4f32 = alias i64 (i64), <4 x float> (<4 x float>)* @func_v4f32 +@alias_i64_to_v4f32 = alias bitcast (<4 x float> (<4 x float>)* @func_v4f32 to i64 (i64)*) ; Test cast between vector and scalar with different number of bits -@alias_v4f32_to_i64 = alias <4 x float> (<4 x float>), i64 (i64)* @func_i64 +@alias_v4f32_to_i64 = alias bitcast (i64 (i64)* @func_i64 to <4 x float> (<4 x float>)*) ; Test cast from scalar to vector of pointers with same number of bits ; We don't know the pointer size at this point, so this can't be done -@alias_i64_to_v2i32p = alias i64 (i64), <2 x i32*> (<2 x i32*>)* @func_v2i32p +@alias_i64_to_v2i32p = alias bitcast (<2 x i32*> (<2 x i32*>)* @func_v2i32p to i64 (i64)*) ; Test cast between vector of pointers and scalar with different number of bits -@alias_v4i32p_to_i64 = alias <4 x i32*> (<4 x i32*>), i64 (i64)* @func_i64 +@alias_v4i32p_to_i64 = alias bitcast (i64 (i64)* @func_i64 to <4 x i32*> (<4 x i32*>)*) diff --git a/test/Transforms/InstCombine/cast.ll b/test/Transforms/InstCombine/cast.ll index 4fab92f..0cbfbb0 100644 --- a/test/Transforms/InstCombine/cast.ll +++ b/test/Transforms/InstCombine/cast.ll @@ -370,7 +370,7 @@ define zeroext i64 @test43(i8 zeroext %on_off) nounwind readonly { ret i64 %C ;; Should be (add (zext i8 -> i64), -1) ; CHECK-LABEL: @test43( ; CHECK-NEXT: %A = zext i8 %on_off to i64 -; CHECK-NEXT: %B = add i64 %A, -1 +; CHECK-NEXT: %B = add nsw i64 %A, -1 ; CHECK-NEXT: ret i64 %B } diff --git a/test/Transforms/InstCombine/constant-fold-address-space-pointer.ll b/test/Transforms/InstCombine/constant-fold-address-space-pointer.ll index 9f21d54..7fac78a 100644 --- a/test/Transforms/InstCombine/constant-fold-address-space-pointer.ll +++ b/test/Transforms/InstCombine/constant-fold-address-space-pointer.ll @@ -230,3 +230,13 @@ define i32 @constant_through_array_as_ptrs() { %b = load i32 addrspace(1)* %a, align 4 ret i32 %b } + +@shared_mem = external addrspace(3) global [0 x i8] + +define float @canonicalize_addrspacecast(i32 %i) { +; CHECK-LABEL: @canonicalize_addrspacecast +; CHECK-NEXT: getelementptr inbounds float* addrspacecast (float addrspace(3)* bitcast ([0 x i8] addrspace(3)* @shared_mem to float addrspace(3)*) to float*), i32 %i + %p = getelementptr inbounds float* addrspacecast ([0 x i8] addrspace(3)* @shared_mem to float*), i32 %i + %v = load float* %p + ret float %v +} diff --git a/test/Transforms/InstCombine/descale-zero.ll b/test/Transforms/InstCombine/descale-zero.ll new file mode 100644 index 0000000..7990fdb --- /dev/null +++ b/test/Transforms/InstCombine/descale-zero.ll @@ -0,0 +1,21 @@ +; RUN: opt < %s -instcombine -S | FileCheck %s + +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-apple-macosx10.10.0" + +define internal i8* @descale_zero() { +entry: +; CHECK: load i16** inttoptr (i64 48 to i16**), align 16 +; CHECK-NEXT: bitcast i16* +; CHECK-NEXT: ret i8* + %i16_ptr = load i16** inttoptr (i64 48 to i16**), align 16 + %num = load i64* inttoptr (i64 64 to i64*), align 64 + %num_times_2 = shl i64 %num, 1 + %num_times_2_plus_4 = add i64 %num_times_2, 4 + %i8_ptr = bitcast i16* %i16_ptr to i8* + %i8_ptr_num_times_2_plus_4 = getelementptr i8* %i8_ptr, i64 %num_times_2_plus_4 + %num_times_neg2 = mul i64 %num, -2 + %num_times_neg2_minus_4 = add i64 %num_times_neg2, -4 + %addr = getelementptr i8* %i8_ptr_num_times_2_plus_4, i64 %num_times_neg2_minus_4 + ret i8* %addr +} diff --git a/test/Transforms/InstCombine/distribute.ll b/test/Transforms/InstCombine/distribute.ll new file mode 100644 index 0000000..e6360f8 --- /dev/null +++ b/test/Transforms/InstCombine/distribute.ll @@ -0,0 +1,68 @@ +; RUN: opt < %s -instcombine -S | FileCheck %s + +define i32 @factorize(i32 %x, i32 %y) { +; CHECK-LABEL: @factorize( +; (X | 1) & (X | 2) -> X | (1 & 2) -> X + %l = or i32 %x, 1 + %r = or i32 %x, 2 + %z = and i32 %l, %r + ret i32 %z +; CHECK: ret i32 %x +} + +define i32 @factorize2(i32 %x) { +; CHECK-LABEL: @factorize2( +; 3*X - 2*X -> X + %l = mul i32 3, %x + %r = mul i32 2, %x + %z = sub i32 %l, %r + ret i32 %z +; CHECK: ret i32 %x +} + +define i32 @factorize3(i32 %x, i32 %a, i32 %b) { +; CHECK-LABEL: @factorize3( +; (X | (A|B)) & (X | B) -> X | ((A|B) & B) -> X | B + %aORb = or i32 %a, %b + %l = or i32 %x, %aORb + %r = or i32 %x, %b + %z = and i32 %l, %r + ret i32 %z +; CHECK: %z = or i32 %b, %x +; CHECK: ret i32 %z +} + +define i32 @factorize4(i32 %x, i32 %y) { +; CHECK-LABEL: @factorize4( +; ((Y << 1) * X) - (X * Y) -> (X * (Y * 2 - Y)) -> (X * Y) + %sh = shl i32 %y, 1 + %ml = mul i32 %sh, %x + %mr = mul i32 %x, %y + %s = sub i32 %ml, %mr + ret i32 %s +; CHECK: %s = mul i32 %y, %x +; CHECK: ret i32 %s +} + +define i32 @factorize5(i32 %x, i32 %y) { +; CHECK-LABEL: @factorize5( +; ((Y * 2) * X) - (X * Y) -> (X * Y) + %sh = mul i32 %y, 2 + %ml = mul i32 %sh, %x + %mr = mul i32 %x, %y + %s = sub i32 %ml, %mr + ret i32 %s +; CHECK: %s = mul i32 %y, %x +; CHECK: ret i32 %s +} + +define i32 @expand(i32 %x) { +; CHECK-LABEL: @expand( +; ((X & 1) | 2) & 1 -> ((X & 1) & 1) | (2 & 1) -> (X & 1) | 0 -> X & 1 + %a = and i32 %x, 1 + %b = or i32 %a, 2 + %c = and i32 %b, 1 + ret i32 %c +; CHECK: %a = and i32 %x, 1 +; CHECK: ret i32 %a +} diff --git a/test/Transforms/InstCombine/ffs-1.ll b/test/Transforms/InstCombine/ffs-1.ll index 1dec11d..c8763dc 100644 --- a/test/Transforms/InstCombine/ffs-1.ll +++ b/test/Transforms/InstCombine/ffs-1.ll @@ -103,7 +103,7 @@ define i32 @test_simplify13(i32 %x) { ; CHECK-LABEL: @test_simplify13( %ret = call i32 @ffs(i32 %x) ; CHECK-NEXT: [[CTTZ:%[a-z0-9]+]] = call i32 @llvm.cttz.i32(i32 %x, i1 false) -; CHECK-NEXT: [[INC:%[a-z0-9]+]] = add i32 [[CTTZ]], 1 +; CHECK-NEXT: [[INC:%[a-z0-9]+]] = add nuw nsw i32 [[CTTZ]], 1 ; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp ne i32 %x, 0 ; CHECK-NEXT: [[RET:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[INC]], i32 0 ret i32 %ret @@ -114,7 +114,7 @@ define i32 @test_simplify14(i32 %x) { ; CHECK-LINUX-LABEL: @test_simplify14( %ret = call i32 @ffsl(i32 %x) ; CHECK-LINUX-NEXT: [[CTTZ:%[a-z0-9]+]] = call i32 @llvm.cttz.i32(i32 %x, i1 false) -; CHECK-LINUX-NEXT: [[INC:%[a-z0-9]+]] = add i32 [[CTTZ]], 1 +; CHECK-LINUX-NEXT: [[INC:%[a-z0-9]+]] = add nuw nsw i32 [[CTTZ]], 1 ; CHECK-LINUX-NEXT: [[CMP:%[a-z0-9]+]] = icmp ne i32 %x, 0 ; CHECK-LINUX-NEXT: [[RET:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[INC]], i32 0 ret i32 %ret @@ -125,7 +125,7 @@ define i32 @test_simplify15(i64 %x) { ; CHECK-LINUX-LABEL: @test_simplify15( %ret = call i32 @ffsll(i64 %x) ; CHECK-LINUX-NEXT: [[CTTZ:%[a-z0-9]+]] = call i64 @llvm.cttz.i64(i64 %x, i1 false) -; CHECK-LINUX-NEXT: [[INC:%[a-z0-9]+]] = add i64 [[CTTZ]], 1 +; CHECK-LINUX-NEXT: [[INC:%[a-z0-9]+]] = add nuw nsw i64 [[CTTZ]], 1 ; CHECK-LINUX-NEXT: [[TRUNC:%[a-z0-9]+]] = trunc i64 [[INC]] to i32 ; CHECK-LINUX-NEXT: [[CMP:%[a-z0-9]+]] = icmp ne i64 %x, 0 ; CHECK-LINUX-NEXT: [[RET:%[a-z0-9]+]] = select i1 [[CMP]], i32 [[TRUNC]], i32 0 diff --git a/test/Transforms/InstCombine/gepphigep.ll b/test/Transforms/InstCombine/gepphigep.ll new file mode 100644 index 0000000..9aab609 --- /dev/null +++ b/test/Transforms/InstCombine/gepphigep.ll @@ -0,0 +1,56 @@ +; RUN: opt -instcombine -S < %s | FileCheck %s + +%struct1 = type { %struct2*, i32, i32, i32 } +%struct2 = type { i32, i32 } + +define i32 @test1(%struct1* %dm, i1 %tmp4, i64 %tmp9, i64 %tmp19) { +bb: + %tmp = getelementptr inbounds %struct1* %dm, i64 0, i32 0 + %tmp1 = load %struct2** %tmp, align 8 + br i1 %tmp4, label %bb1, label %bb2 + +bb1: + %tmp10 = getelementptr inbounds %struct2* %tmp1, i64 %tmp9 + %tmp11 = getelementptr inbounds %struct2* %tmp10, i64 0, i32 0 + store i32 0, i32* %tmp11, align 4 + br label %bb3 + +bb2: + %tmp20 = getelementptr inbounds %struct2* %tmp1, i64 %tmp19 + %tmp21 = getelementptr inbounds %struct2* %tmp20, i64 0, i32 0 + store i32 0, i32* %tmp21, align 4 + br label %bb3 + +bb3: + %phi = phi %struct2* [ %tmp10, %bb1 ], [ %tmp20, %bb2 ] + %tmp24 = getelementptr inbounds %struct2* %phi, i64 0, i32 1 + %tmp25 = load i32* %tmp24, align 4 + ret i32 %tmp25 + +; CHECK-LABEL: @test1( +; CHECK: getelementptr inbounds %struct2* %tmp1, i64 %tmp9, i32 0 +; CHECK: getelementptr inbounds %struct2* %tmp1, i64 %tmp19, i32 0 +; CHECK: %[[PHI:[0-9A-Za-z]+]] = phi i64 [ %tmp9, %bb1 ], [ %tmp19, %bb2 ] +; CHECK: getelementptr inbounds %struct2* %tmp1, i64 %[[PHI]], i32 1 + +} + +define i32 @test2(%struct1* %dm, i1 %tmp4, i64 %tmp9, i64 %tmp19) { +bb: + %tmp = getelementptr inbounds %struct1* %dm, i64 0, i32 0 + %tmp1 = load %struct2** %tmp, align 8 + %tmp10 = getelementptr inbounds %struct2* %tmp1, i64 %tmp9 + %tmp11 = getelementptr inbounds %struct2* %tmp10, i64 0, i32 0 + store i32 0, i32* %tmp11, align 4 + %tmp20 = getelementptr inbounds %struct2* %tmp1, i64 %tmp19 + %tmp21 = getelementptr inbounds %struct2* %tmp20, i64 0, i32 0 + store i32 0, i32* %tmp21, align 4 + %tmp24 = getelementptr inbounds %struct2* %tmp10, i64 0, i32 1 + %tmp25 = load i32* %tmp24, align 4 + ret i32 %tmp25 + +; CHECK-LABEL: @test2( +; CHECK: getelementptr inbounds %struct2* %tmp1, i64 %tmp9, i32 0 +; CHECK: getelementptr inbounds %struct2* %tmp1, i64 %tmp19, i32 0 +; CHECK: getelementptr inbounds %struct2* %tmp1, i64 %tmp9, i32 1 +} diff --git a/test/Transforms/InstCombine/getelementptr.ll b/test/Transforms/InstCombine/getelementptr.ll index ef0cb29..3240c6d 100644 --- a/test/Transforms/InstCombine/getelementptr.ll +++ b/test/Transforms/InstCombine/getelementptr.ll @@ -732,7 +732,8 @@ define i64 @test_gep_bitcast_array_same_size_element([100 x double]* %arr, i64 % define i64 @test_gep_bitcast_array_same_size_element_addrspacecast([100 x double]* %arr, i64 %N) { ; CHECK-LABEL: @test_gep_bitcast_array_same_size_element_addrspacecast( ; CHECK: getelementptr [100 x double]* %arr, i64 0, i64 %V -; CHECK-NEXT: %t = addrspacecast double* +; CHECK-NEXT: bitcast double* +; CHECK-NEXT: %t = addrspacecast i64* ; CHECK: load i64 addrspace(3)* %t %cast = addrspacecast [100 x double]* %arr to i64 addrspace(3)* %V = mul i64 %N, 8 @@ -802,10 +803,22 @@ define i16 @test41([3 x i32] addrspace(1)* %array) { ; CHECK-NEXT: ret i16 8 } -define i32 addrspace(1)* @ascast_0_gep([128 x i32]* %p) nounwind { +define i32 addrspace(1)* @ascast_0_gep(i32* %p) nounwind { ; CHECK-LABEL: @ascast_0_gep( ; CHECK-NOT: getelementptr ; CHECK: ret + %gep = getelementptr i32* %p, i32 0 + %x = addrspacecast i32* %gep to i32 addrspace(1)* + ret i32 addrspace(1)* %x +} + +; Do not merge the GEP and the addrspacecast, because it would undo the +; addrspacecast canonicalization. +define i32 addrspace(1)* @ascast_0_0_gep([128 x i32]* %p) nounwind { +; CHECK-LABEL: @ascast_0_0_gep( +; CHECK-NEXT: getelementptr [128 x i32] +; CHECK-NEXT: addrspacecast i32* +; CHECK-NEXT: ret i32 addrspace(1)* %gep = getelementptr [128 x i32]* %p, i32 0, i32 0 %x = addrspacecast i32* %gep to i32 addrspace(1)* ret i32 addrspace(1)* %x diff --git a/test/Transforms/InstCombine/icmp.ll b/test/Transforms/InstCombine/icmp.ll index f45897c..26e144f 100644 --- a/test/Transforms/InstCombine/icmp.ll +++ b/test/Transforms/InstCombine/icmp.ll @@ -1,7 +1,6 @@ ; RUN: opt < %s -instcombine -S | FileCheck %s -target datalayout = -"e-p:64:64:64-p1:16:16:16-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" +target datalayout = "e-p:64:64:64-p1:16:16:16-p2:32:32:32-p3:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" define i32 @test1(i32 %X) { entry: @@ -166,6 +165,14 @@ define i1 @test17(i32 %x) nounwind { ; CHECK-NEXT: %cmp = icmp ne i32 %x, 3 } +define i1 @test17a(i32 %x) nounwind { + %shl = shl i32 1, %x + %and = and i32 %shl, 7 + %cmp = icmp eq i32 %and, 0 + ret i1 %cmp +; CHECK-LABEL: @test17a( +; CHECK-NEXT: %cmp = icmp ugt i32 %x, 2 +} define i1 @test18(i32 %x) nounwind { %sh = lshr i32 8, %x @@ -194,6 +201,15 @@ define i1 @test20(i32 %x) nounwind { ; CHECK-NEXT: %cmp = icmp eq i32 %x, 3 } +define i1 @test20a(i32 %x) nounwind { + %shl = shl i32 1, %x + %and = and i32 %shl, 7 + %cmp = icmp ne i32 %and, 0 + ret i1 %cmp +; CHECK-LABEL: @test20a( +; CHECK-NEXT: %cmp = icmp ult i32 %x, 3 +} + define i1 @test21(i8 %x, i8 %y) { ; CHECK-LABEL: @test21( ; CHECK-NOT: or i8 @@ -657,6 +673,49 @@ define i1 @test60_as1(i8 addrspace(1)* %foo, i64 %i, i64 %j) { ; CHECK-NEXT: ret i1 } +; Same as test60, but look through an addrspacecast instead of a +; bitcast. This uses the same sized addrspace. +define i1 @test60_addrspacecast(i8* %foo, i64 %i, i64 %j) { + %bit = addrspacecast i8* %foo to i32 addrspace(3)* + %gep1 = getelementptr inbounds i32 addrspace(3)* %bit, i64 %i + %gep2 = getelementptr inbounds i8* %foo, i64 %j + %cast1 = addrspacecast i32 addrspace(3)* %gep1 to i8* + %cmp = icmp ult i8* %cast1, %gep2 + ret i1 %cmp +; CHECK-LABEL: @test60_addrspacecast( +; CHECK-NEXT: %gep1.idx = shl nuw i64 %i, 2 +; CHECK-NEXT: icmp slt i64 %gep1.idx, %j +; CHECK-NEXT: ret i1 +} + +define i1 @test60_addrspacecast_smaller(i8* %foo, i16 %i, i64 %j) { + %bit = addrspacecast i8* %foo to i32 addrspace(1)* + %gep1 = getelementptr inbounds i32 addrspace(1)* %bit, i16 %i + %gep2 = getelementptr inbounds i8* %foo, i64 %j + %cast1 = addrspacecast i32 addrspace(1)* %gep1 to i8* + %cmp = icmp ult i8* %cast1, %gep2 + ret i1 %cmp +; CHECK-LABEL: @test60_addrspacecast_smaller( +; CHECK-NEXT: %gep1.idx = shl nuw i16 %i, 2 +; CHECK-NEXT: trunc i64 %j to i16 +; CHECK-NEXT: icmp sgt i16 %1, %gep1.idx +; CHECK-NEXT: ret i1 +} + +define i1 @test60_addrspacecast_larger(i8 addrspace(1)* %foo, i32 %i, i16 %j) { + %bit = addrspacecast i8 addrspace(1)* %foo to i32 addrspace(2)* + %gep1 = getelementptr inbounds i32 addrspace(2)* %bit, i32 %i + %gep2 = getelementptr inbounds i8 addrspace(1)* %foo, i16 %j + %cast1 = addrspacecast i32 addrspace(2)* %gep1 to i8 addrspace(1)* + %cmp = icmp ult i8 addrspace(1)* %cast1, %gep2 + ret i1 %cmp +; CHECK-LABEL: @test60_addrspacecast_larger( +; CHECK-NEXT: %gep1.idx = shl nuw i32 %i, 2 +; CHECK-NEXT: trunc i32 %gep1.idx to i16 +; CHECK-NEXT: icmp slt i16 %1, %j +; CHECK-NEXT: ret i1 +} + define i1 @test61(i8* %foo, i64 %i, i64 %j) { %bit = bitcast i8* %foo to i32* %gep1 = getelementptr i32* %bit, i64 %i diff --git a/test/Transforms/InstCombine/intrinsics.ll b/test/Transforms/InstCombine/intrinsics.ll index 91c4470..9b58d93 100644 --- a/test/Transforms/InstCombine/intrinsics.ll +++ b/test/Transforms/InstCombine/intrinsics.ll @@ -3,6 +3,7 @@ %overflow.result = type {i8, i1} declare %overflow.result @llvm.uadd.with.overflow.i8(i8, i8) +declare { i32, i1 } @llvm.sadd.with.overflow.i32(i32, i32) declare %overflow.result @llvm.umul.with.overflow.i8(i8, i8) declare double @llvm.powi.f64(double, i32) nounwind readonly declare i32 @llvm.cttz.i32(i32, i1) nounwind readnone @@ -89,6 +90,18 @@ define i8 @uaddtest7(i8 %A, i8 %B) { ; CHECK-NEXT: ret i8 %z } +; PR20194 +define { i32, i1 } @saddtest1(i8 %a, i8 %b) { + %A = sext i8 %a to i32 + %B = sext i8 %b to i32 + %x = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %A, i32 %B) + ret { i32, i1 } %x +; CHECK-LABEL: @saddtest1 +; CHECK: %x = add nsw i32 %A, %B +; CHECK-NEXT: %1 = insertvalue { i32, i1 } { i32 undef, i1 false }, i32 %x, 0 +; CHECK-NEXT: ret { i32, i1 } %1 +} + define i8 @umultest1(i8 %A, i1* %overflowPtr) { %x = call %overflow.result @llvm.umul.with.overflow.i8(i8 0, i8 %A) diff --git a/test/Transforms/InstCombine/memcpy-from-global.ll b/test/Transforms/InstCombine/memcpy-from-global.ll index b5a0ab8..3bc1d36 100644 --- a/test/Transforms/InstCombine/memcpy-from-global.ll +++ b/test/Transforms/InstCombine/memcpy-from-global.ll @@ -78,7 +78,8 @@ define void @test2_addrspacecast() { ; %A alloca is deleted ; This doesn't exactly match what test2 does, because folding the type ; cast into the alloca doesn't work for the addrspacecast yet. -; CHECK-NEXT: alloca %T +; CHECK-NEXT: alloca [124 x i8] +; CHECK-NEXT: getelementptr ; CHECK-NEXT: addrspacecast ; use @G instead of %A diff --git a/test/Transforms/InstCombine/overflow-mul.ll b/test/Transforms/InstCombine/overflow-mul.ll index 04019ae..cbb2f5f 100644 --- a/test/Transforms/InstCombine/overflow-mul.ll +++ b/test/Transforms/InstCombine/overflow-mul.ll @@ -162,3 +162,14 @@ entry: ret i32 %retval } +define <4 x i32> @pr20113(<4 x i16> %a, <4 x i16> %b) { +; CHECK-LABEL: @pr20113 +; CHECK-NOT: mul.with.overflow +; CHECK: ret + %vmovl.i.i726 = zext <4 x i16> %a to <4 x i32> + %vmovl.i.i712 = zext <4 x i16> %b to <4 x i32> + %mul.i703 = mul <4 x i32> %vmovl.i.i712, %vmovl.i.i726 + %tmp = icmp sge <4 x i32> %mul.i703, zeroinitializer + %vcgez.i = sext <4 x i1> %tmp to <4 x i32> + ret <4 x i32> %vcgez.i +} diff --git a/test/Transforms/InstCombine/pr20059.ll b/test/Transforms/InstCombine/pr20059.ll new file mode 100644 index 0000000..0ef3159 --- /dev/null +++ b/test/Transforms/InstCombine/pr20059.ll @@ -0,0 +1,16 @@ +; RUN: opt -S -instcombine < %s | FileCheck %s + +; In PR20059 ( http://llvm.org/pr20059 ), shufflevector operations are reordered/removed +; for an srem operation. This is not a valid optimization because it may cause a trap +; on div-by-zero. + +; CHECK-LABEL: @do_not_reorder +; CHECK: %splat1 = shufflevector <4 x i32> %p1, <4 x i32> undef, <4 x i32> zeroinitializer +; CHECK-NEXT: %splat2 = shufflevector <4 x i32> %p2, <4 x i32> undef, <4 x i32> zeroinitializer +; CHECK-NEXT: %retval = srem <4 x i32> %splat1, %splat2 +define <4 x i32> @do_not_reorder(<4 x i32> %p1, <4 x i32> %p2) { + %splat1 = shufflevector <4 x i32> %p1, <4 x i32> undef, <4 x i32> zeroinitializer + %splat2 = shufflevector <4 x i32> %p2, <4 x i32> undef, <4 x i32> zeroinitializer + %retval = srem <4 x i32> %splat1, %splat2 + ret <4 x i32> %retval +} diff --git a/test/Transforms/InstCombine/pr20079.ll b/test/Transforms/InstCombine/pr20079.ll new file mode 100644 index 0000000..ce9c4de --- /dev/null +++ b/test/Transforms/InstCombine/pr20079.ll @@ -0,0 +1,9 @@ +; RUN: opt -S -instcombine < %s | FileCheck %s +@b = internal global [1 x i32] zeroinitializer, align 4 +@c = internal global i32 0, align 4 + +; CHECK-LABEL: @fn1 +; CHECK-NEXT: ret i32 0 +define i32 @fn1(i32 %a) { + ret i32 0 +} diff --git a/test/Transforms/InstCombine/r600-intrinsics.ll b/test/Transforms/InstCombine/r600-intrinsics.ll new file mode 100644 index 0000000..1db6b0d --- /dev/null +++ b/test/Transforms/InstCombine/r600-intrinsics.ll @@ -0,0 +1,47 @@ +; RUN: opt -instcombine -S < %s | FileCheck %s + +declare float @llvm.AMDGPU.rcp.f32(float) nounwind readnone +declare double @llvm.AMDGPU.rcp.f64(double) nounwind readnone + +; CHECK-LABEL: @test_constant_fold_rcp_f32_1 +; CHECK-NEXT: ret float 1.000000e+00 +define float @test_constant_fold_rcp_f32_1() nounwind { + %val = call float @llvm.AMDGPU.rcp.f32(float 1.0) nounwind readnone + ret float %val +} + +; CHECK-LABEL: @test_constant_fold_rcp_f64_1 +; CHECK-NEXT: ret double 1.000000e+00 +define double @test_constant_fold_rcp_f64_1() nounwind { + %val = call double @llvm.AMDGPU.rcp.f64(double 1.0) nounwind readnone + ret double %val +} + +; CHECK-LABEL: @test_constant_fold_rcp_f32_half +; CHECK-NEXT: ret float 2.000000e+00 +define float @test_constant_fold_rcp_f32_half() nounwind { + %val = call float @llvm.AMDGPU.rcp.f32(float 0.5) nounwind readnone + ret float %val +} + +; CHECK-LABEL: @test_constant_fold_rcp_f64_half +; CHECK-NEXT: ret double 2.000000e+00 +define double @test_constant_fold_rcp_f64_half() nounwind { + %val = call double @llvm.AMDGPU.rcp.f64(double 0.5) nounwind readnone + ret double %val +} + +; CHECK-LABEL: @test_constant_fold_rcp_f32_43 +; CHECK-NEXT: call float @llvm.AMDGPU.rcp.f32(float 4.300000e+01) +define float @test_constant_fold_rcp_f32_43() nounwind { + %val = call float @llvm.AMDGPU.rcp.f32(float 4.300000e+01) nounwind readnone + ret float %val +} + +; CHECK-LABEL: @test_constant_fold_rcp_f64_43 +; CHECK-NEXT: call double @llvm.AMDGPU.rcp.f64(double 4.300000e+01) +define double @test_constant_fold_rcp_f64_43() nounwind { + %val = call double @llvm.AMDGPU.rcp.f64(double 4.300000e+01) nounwind readnone + ret double %val +} + diff --git a/test/Transforms/InstCombine/rem.ll b/test/Transforms/InstCombine/rem.ll index 9f07702..0595a67 100644 --- a/test/Transforms/InstCombine/rem.ll +++ b/test/Transforms/InstCombine/rem.ll @@ -127,7 +127,7 @@ define i64 @test14(i64 %x, i32 %y) { ; CHECK-LABEL: @test14( ; CHECK-NEXT: [[SHL:%.*]] = shl i32 1, %y ; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[SHL]] to i64 -; CHECK-NEXT: [[ADD:%.*]] = add i64 [[ZEXT]], -1 +; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[ZEXT]], -1 ; CHECK-NEXT: [[AND:%.*]] = and i64 [[ADD]], %x ; CHECK-NEXT: ret i64 [[AND]] %shl = shl i32 1, %y diff --git a/test/Transforms/InstCombine/select.ll b/test/Transforms/InstCombine/select.ll index 2213be1..d625f3b 100644 --- a/test/Transforms/InstCombine/select.ll +++ b/test/Transforms/InstCombine/select.ll @@ -281,7 +281,7 @@ define i32 @test15i(i32 %X) { ; CHECK-NEXT: %t1 = shl i32 %X, 8 ; CHECK-NEXT: %1 = and i32 %t1, 512 ; CHECK-NEXT: %2 = xor i32 %1, 512 -; CHECK-NEXT: %3 = add i32 %2, 577 +; CHECK-NEXT: %3 = add nuw nsw i32 %2, 577 ; CHECK-NEXT: ret i32 %3 } @@ -294,7 +294,7 @@ define i32 @test15j(i32 %X) { ; CHECK-LABEL: @test15j( ; CHECK-NEXT: %t1 = shl i32 %X, 8 ; CHECK-NEXT: %1 = and i32 %t1, 512 -; CHECK-NEXT: %2 = add i32 %1, 577 +; CHECK-NEXT: %2 = add nuw nsw i32 %1, 577 ; CHECK-NEXT: ret i32 %2 } @@ -521,7 +521,7 @@ define i32 @test35(i32 %x) { ; CHECK-LABEL: @test35( ; CHECK: ashr i32 %x, 31 ; CHECK: and i32 {{.*}}, 40 -; CHECK: add i32 {{.*}}, 60 +; CHECK: add nuw nsw i32 {{.*}}, 60 ; CHECK: ret } @@ -532,7 +532,7 @@ define i32 @test36(i32 %x) { ; CHECK-LABEL: @test36( ; CHECK: ashr i32 %x, 31 ; CHECK: and i32 {{.*}}, -40 -; CHECK: add i32 {{.*}}, 100 +; CHECK: add nsw i32 {{.*}}, 100 ; CHECK: ret } @@ -996,6 +996,111 @@ define <2 x i32> @select_icmp_eq_and_1_0_or_vector_of_2s(i32 %x, <2 x i32> %y) { ret <2 x i32> %select } +; CHECK-LABEL: @select_icmp_and_8_eq_0_or_8( +; CHECK-NEXT: [[OR:%[a-z0-9]+]] = or i32 %x, 8 +; CHECK-NEXT: ret i32 [[OR]] +define i32 @select_icmp_and_8_eq_0_or_8(i32 %x) { + %and = and i32 %x, 8 + %cmp = icmp eq i32 %and, 0 + %or = or i32 %x, 8 + %or.x = select i1 %cmp, i32 %or, i32 %x + ret i32 %or.x +} + +; CHECK-LABEL: @select_icmp_and_8_ne_0_xor_8( +; CHECK-NEXT: [[AND:%[a-z0-9]+]] = and i32 %x, -9 +; CHECK-NEXT: ret i32 [[AND]] +define i32 @select_icmp_and_8_ne_0_xor_8(i32 %x) { + %and = and i32 %x, 8 + %cmp = icmp eq i32 %and, 0 + %xor = xor i32 %x, 8 + %x.xor = select i1 %cmp, i32 %x, i32 %xor + ret i32 %x.xor +} + +; CHECK-LABEL: @select_icmp_and_8_eq_0_xor_8( +; CHECK-NEXT: [[OR:%[a-z0-9]+]] = or i32 %x, 8 +; CHECK-NEXT: ret i32 [[OR]] +define i32 @select_icmp_and_8_eq_0_xor_8(i32 %x) { + %and = and i32 %x, 8 + %cmp = icmp eq i32 %and, 0 + %xor = xor i32 %x, 8 + %xor.x = select i1 %cmp, i32 %xor, i32 %x + ret i32 %xor.x +} + +; CHECK-LABEL: @select_icmp_and_8_ne_0_and_not_8( +; CHECK-NEXT: [[AND:%[a-z0-9]+]] = and i32 %x, -9 +; CHECK-NEXT: ret i32 [[AND]] +define i32 @select_icmp_and_8_ne_0_and_not_8(i32 %x) { + %and = and i32 %x, 8 + %cmp = icmp eq i32 %and, 0 + %and1 = and i32 %x, -9 + %x.and1 = select i1 %cmp, i32 %x, i32 %and1 + ret i32 %x.and1 +} + +; CHECK-LABEL: @select_icmp_and_8_eq_0_and_not_8( +; CHECK-NEXT: ret i32 %x +define i32 @select_icmp_and_8_eq_0_and_not_8(i32 %x) { + %and = and i32 %x, 8 + %cmp = icmp eq i32 %and, 0 + %and1 = and i32 %x, -9 + %and1.x = select i1 %cmp, i32 %and1, i32 %x + ret i32 %and1.x +} + +; CHECK-LABEL: @select_icmp_x_and_8_eq_0_y_xor_8( +; CHECK: select i1 %cmp, i64 %y, i64 %xor +define i64 @select_icmp_x_and_8_eq_0_y_xor_8(i32 %x, i64 %y) { + %and = and i32 %x, 8 + %cmp = icmp eq i32 %and, 0 + %xor = xor i64 %y, 8 + %y.xor = select i1 %cmp, i64 %y, i64 %xor + ret i64 %y.xor +} + +; CHECK-LABEL: @select_icmp_x_and_8_eq_0_y_and_not_8( +; CHECK: select i1 %cmp, i64 %y, i64 %and1 +define i64 @select_icmp_x_and_8_eq_0_y_and_not_8(i32 %x, i64 %y) { + %and = and i32 %x, 8 + %cmp = icmp eq i32 %and, 0 + %and1 = and i64 %y, -9 + %y.and1 = select i1 %cmp, i64 %y, i64 %and1 + ret i64 %y.and1 +} + +; CHECK-LABEL: @select_icmp_x_and_8_ne_0_y_xor_8( +; CHECK: select i1 %cmp, i64 %xor, i64 %y +define i64 @select_icmp_x_and_8_ne_0_y_xor_8(i32 %x, i64 %y) { + %and = and i32 %x, 8 + %cmp = icmp eq i32 %and, 0 + %xor = xor i64 %y, 8 + %xor.y = select i1 %cmp, i64 %xor, i64 %y + ret i64 %xor.y +} + +; CHECK-LABEL: @select_icmp_x_and_8_ne_0_y_and_not_8( +; CHECK: select i1 %cmp, i64 %and1, i64 %y +define i64 @select_icmp_x_and_8_ne_0_y_and_not_8(i32 %x, i64 %y) { + %and = and i32 %x, 8 + %cmp = icmp eq i32 %and, 0 + %and1 = and i64 %y, -9 + %and1.y = select i1 %cmp, i64 %and1, i64 %y + ret i64 %and1.y +} + +; CHECK-LABEL: @select_icmp_x_and_8_ne_0_y_or_8( +; CHECK: xor i64 %1, 8 +; CHECK: or i64 %2, %y +define i64 @select_icmp_x_and_8_ne_0_y_or_8(i32 %x, i64 %y) { + %and = and i32 %x, 8 + %cmp = icmp eq i32 %and, 0 + %or = or i64 %y, 8 + %or.y = select i1 %cmp, i64 %or, i64 %y + ret i64 %or.y +} + define i32 @test65(i64 %x) { %1 = and i64 %x, 16 %2 = icmp ne i64 %1, 0 @@ -1130,4 +1235,4 @@ define i32 @test75(i32 %x) { ; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp ult i32 %x, 68 ; CHECK-NEXT: [[SEL:%[a-z0-9]+]] = select i1 [[CMP]], i32 68, i32 %x ; CHECK-NEXT: ret i32 [[SEL]] -}
\ No newline at end of file +} diff --git a/test/Transforms/InstCombine/sext.ll b/test/Transforms/InstCombine/sext.ll index b8dfe22..f04afcc 100644 --- a/test/Transforms/InstCombine/sext.ll +++ b/test/Transforms/InstCombine/sext.ll @@ -145,7 +145,7 @@ define i32 @test13(i32 %x) nounwind { ; CHECK-LABEL: @test13( ; CHECK-NEXT: %and = lshr i32 %x, 3 ; CHECK-NEXT: %1 = and i32 %and, 1 -; CHECK-NEXT: %sext = add i32 %1, -1 +; CHECK-NEXT: %sext = add nsw i32 %1, -1 ; CHECK-NEXT: ret i32 %sext } @@ -157,7 +157,7 @@ define i32 @test14(i16 %x) nounwind { ; CHECK-LABEL: @test14( ; CHECK-NEXT: %and = lshr i16 %x, 4 ; CHECK-NEXT: %1 = and i16 %and, 1 -; CHECK-NEXT: %sext = add i16 %1, -1 +; CHECK-NEXT: %sext = add nsw i16 %1, -1 ; CHECK-NEXT: %ext = sext i16 %sext to i32 ; CHECK-NEXT: ret i32 %ext } diff --git a/test/Transforms/InstCombine/sub.ll b/test/Transforms/InstCombine/sub.ll index 41d803c8..67b7c49 100644 --- a/test/Transforms/InstCombine/sub.ll +++ b/test/Transforms/InstCombine/sub.ll @@ -444,3 +444,23 @@ define <2 x i64> @test36(<2 x i64> %A) { ; CHECK-NEXT: %sub = mul <2 x i64> %A, <i64 7, i64 15> ; CHECK-NEXT: ret <2 x i64> %sub } + +define <2 x i32> @test37(<2 x i32> %A) { + %div = sdiv <2 x i32> %A, <i32 -2147483648, i32 -2147483648> + %sub = sub nsw <2 x i32> zeroinitializer, %div + ret <2 x i32> %sub +; CHECK-LABEL: @test37( +; CHECK-NEXT: [[ICMP:%.*]] = icmp eq <2 x i32> %A, <i32 -2147483648, i32 -2147483648> +; CHECK-NEXT: [[SEXT:%.*]] = sext <2 x i1> [[ICMP]] to <2 x i32> +; CHECK-NEXT: ret <2 x i32> [[SEXT]] +} + +define i32 @test38(i32 %A) { + %div = sdiv i32 %A, -2147483648 + %sub = sub nsw i32 0, %div + ret i32 %sub +; CHECK-LABEL: @test38( +; CHECK-NEXT: [[ICMP:%.*]] = icmp eq i32 %A, -2147483648 +; CHECK-NEXT: [[SEXT:%.*]] = sext i1 [[ICMP]] to i32 +; CHECK-NEXT: ret i32 [[SEXT]] +} diff --git a/test/Transforms/InstCombine/vec_shuffle.ll b/test/Transforms/InstCombine/vec_shuffle.ll index fc0f8bd..eb4e9d6 100644 --- a/test/Transforms/InstCombine/vec_shuffle.ll +++ b/test/Transforms/InstCombine/vec_shuffle.ll @@ -405,3 +405,12 @@ define i32 @pr19737(<4 x i32> %in0) { %rv = extractelement <4 x i32> %and.i, i32 0 ret i32 %rv } + +define <4 x i32> @pr20114(<4 x i32> %__mask) { +; CHECK-LABEL: @pr20114 +; CHECK: shufflevector +; CHECK: and + %mask01.i = shufflevector <4 x i32> %__mask, <4 x i32> undef, <4 x i32> <i32 0, i32 0, i32 1, i32 1> + %masked_new.i.i.i = and <4 x i32> bitcast (<2 x i64> <i64 ptrtoint (<4 x i32> (<4 x i32>)* @pr20114 to i64), i64 ptrtoint (<4 x i32> (<4 x i32>)* @pr20114 to i64)> to <4 x i32>), %mask01.i + ret <4 x i32> %masked_new.i.i.i +} diff --git a/test/Transforms/InstCombine/zext-bool-add-sub.ll b/test/Transforms/InstCombine/zext-bool-add-sub.ll index d7f338b..6fa4d70 100644 --- a/test/Transforms/InstCombine/zext-bool-add-sub.ll +++ b/test/Transforms/InstCombine/zext-bool-add-sub.ll @@ -6,7 +6,7 @@ entry: ; CHECK-LABEL: @a( ; CHECK: [[TMP1:%.*]] = sext i1 %y to i32 ; CHECK: [[TMP2:%.*]] = select i1 %x, i32 2, i32 1 -; CHECK-NEXT: add i32 [[TMP2]], [[TMP1]] +; CHECK-NEXT: add nsw i32 [[TMP2]], [[TMP1]] %conv = zext i1 %x to i32 %conv3 = zext i1 %y to i32 %conv3.neg = sub i32 0, %conv3 |