diff --git a/llvm/test/Transforms/InstCombine/and-xor-or.ll b/llvm/test/Transforms/InstCombine/and-xor-or.ll --- a/llvm/test/Transforms/InstCombine/and-xor-or.ll +++ b/llvm/test/Transforms/InstCombine/and-xor-or.ll @@ -4367,6 +4367,30 @@ ret i32 %r } +define i32 @canonicalize_logic_first_or0_nsw(i32 %x) { +; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or0_nsw +; CHECK-SAME: (i32 [[X:%.*]]) { +; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[X]], 15 +; CHECK-NEXT: [[R:%.*]] = add i32 [[TMP1]], 112 +; CHECK-NEXT: ret i32 [[R]] +; + %a = add nsw i32 %x, 112 ; 01110000 + %r = or i32 %a, 15 ; 00001111 + ret i32 %r +} + +define i32 @canonicalize_logic_first_or0_nswnuw(i32 %x) { +; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or0_nswnuw +; CHECK-SAME: (i32 [[X:%.*]]) { +; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[X]], 15 +; CHECK-NEXT: [[R:%.*]] = add i32 [[TMP1]], 112 +; CHECK-NEXT: ret i32 [[R]] +; + %a = add nsw nuw i32 %x, 112 ; 01110000 + %r = or i32 %a, 15 ; 00001111 + ret i32 %r +} + define <2 x i32> @canonicalize_logic_first_or_vector0(<2 x i32> %x) { ; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or_vector0 ; CHECK-SAME: (<2 x i32> [[X:%.*]]) { @@ -4379,7 +4403,30 @@ ret <2 x i32> %r } -; elementwise these constants should be ok to canonicalize logic op then math +define <2 x i32> @canonicalize_logic_first_or_vector0_nsw(<2 x i32> %x) { +; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or_vector0_nsw +; CHECK-SAME: (<2 x i32> [[X:%.*]]) { +; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i32> [[X]], +; CHECK-NEXT: [[R:%.*]] = add <2 x i32> [[TMP1]], +; CHECK-NEXT: ret <2 x i32> [[R]] +; + %a = add nsw <2 x i32> , %x ; <0x00000070, 0x00000070> + %r = or <2 x i32> , %a ; <0x0000000F, 0x0000000F> + ret <2 x i32> %r +} + +define <2 x i32> @canonicalize_logic_first_or_vector0_nswnuw(<2 x i32> %x) { +; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or_vector0_nswnuw +; CHECK-SAME: (<2 x i32> [[X:%.*]]) { +; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i32> [[X]], +; CHECK-NEXT: [[R:%.*]] = add <2 x i32> [[TMP1]], +; CHECK-NEXT: ret <2 x i32> [[R]] +; + %a = add nsw nuw <2 x i32> , %x ; <0x00000070, 0x00000070> + %r = or <2 x i32> , %a ; <0x0000000F, 0x0000000F> + ret <2 x i32> %r +} + define <2 x i32> @canonicalize_logic_first_or_vector1(<2 x i32> %x) { ; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or_vector1 ; CHECK-SAME: (<2 x i32> [[X:%.*]]) { @@ -4392,6 +4439,30 @@ ret <2 x i32> %r } +define <2 x i32> @canonicalize_logic_first_or_vector1_nsw(<2 x i32> %x) { +; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or_vector1_nsw +; CHECK-SAME: (<2 x i32> [[X:%.*]]) { +; CHECK-NEXT: [[A:%.*]] = add nsw <2 x i32> [[X]], +; CHECK-NEXT: [[R:%.*]] = or <2 x i32> [[A]], +; CHECK-NEXT: ret <2 x i32> [[R]] +; + %a = add nsw <2 x i32> , %x ; <0xFF800000, 0x7B800000> + %r = or <2 x i32> , %a ; <0x0000800F, 0x0000080F> + ret <2 x i32> %r +} + +define <2 x i32> @canonicalize_logic_first_or_vector1_nswnuw(<2 x i32> %x) { +; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or_vector1_nswnuw +; CHECK-SAME: (<2 x i32> [[X:%.*]]) { +; CHECK-NEXT: [[A:%.*]] = add nuw nsw <2 x i32> [[X]], +; CHECK-NEXT: [[R:%.*]] = or <2 x i32> [[A]], +; CHECK-NEXT: ret <2 x i32> [[R]] +; + %a = add nsw nuw <2 x i32> , %x ; <0xFF800000, 0x7B800000> + %r = or <2 x i32> , %a ; <0x0000800F, 0x0000080F> + ret <2 x i32> %r +} + define <2 x i32> @canonicalize_logic_first_or_vector2(<2 x i32> %x) { ; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_or_vector2 ; CHECK-SAME: (<2 x i32> [[X:%.*]]) { @@ -4442,6 +4513,30 @@ ret i8 %r } +define i8 @canonicalize_logic_first_and0_nsw(i8 %x) { +; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and0_nsw +; CHECK-SAME: (i8 [[X:%.*]]) { +; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X]], -10 +; CHECK-NEXT: [[R:%.*]] = add i8 [[TMP1]], 48 +; CHECK-NEXT: ret i8 [[R]] +; + %b = add nsw i8 %x, 48 ; 00110000 + %r = and i8 %b, -10 ; 11110110 + ret i8 %r +} + +define i8 @canonicalize_logic_first_and0_nswnuw(i8 %x) { +; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and0_nswnuw +; CHECK-SAME: (i8 [[X:%.*]]) { +; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X]], -10 +; CHECK-NEXT: [[R:%.*]] = add i8 [[TMP1]], 48 +; CHECK-NEXT: ret i8 [[R]] +; + %b = add nsw nuw i8 %x, 48 ; 00110000 + %r = and i8 %b, -10 ; 11110110 + ret i8 %r +} + define <2 x i8> @canonicalize_logic_first_and_vector0(<2 x i8> %x) { ; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and_vector0 ; CHECK-SAME: (<2 x i8> [[X:%.*]]) { @@ -4454,6 +4549,30 @@ ret <2 x i8> %r } +define <2 x i8> @canonicalize_logic_first_and_vector0_nsw(<2 x i8> %x) { +; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and_vector0_nsw +; CHECK-SAME: (<2 x i8> [[X:%.*]]) { +; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X]], +; CHECK-NEXT: [[R:%.*]] = add <2 x i8> [[TMP1]], +; CHECK-NEXT: ret <2 x i8> [[R]] +; + %a = add nsw <2 x i8> , %x + %r = and <2 x i8> , %a + ret <2 x i8> %r +} + +define <2 x i8> @canonicalize_logic_first_and_vector0_nswnuw(<2 x i8> %x) { +; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and_vector0_nswnuw +; CHECK-SAME: (<2 x i8> [[X:%.*]]) { +; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i8> [[X]], +; CHECK-NEXT: [[R:%.*]] = add <2 x i8> [[TMP1]], +; CHECK-NEXT: ret <2 x i8> [[R]] +; + %a = add nsw nuw <2 x i8> , %x + %r = and <2 x i8> , %a + ret <2 x i8> %r +} + ; element-wise the constants match constraints define <2 x i8> @canonicalize_logic_first_and_vector1(<2 x i8> %x) { ; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_and_vector1 @@ -4531,6 +4650,30 @@ ret i8 %r } +define i8 @canonicalize_logic_first_xor_0_nsw(i8 %x) { +; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_xor_0_nsw +; CHECK-SAME: (i8 [[X:%.*]]) { +; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[X]], 31 +; CHECK-NEXT: [[R:%.*]] = add i8 [[TMP1]], 96 +; CHECK-NEXT: ret i8 [[R]] +; + %a = add nsw i8 %x, 96 ; 01100000 + %r = xor i8 %a, 31 ; 00011111 + ret i8 %r +} + +define i8 @canonicalize_logic_first_xor_0_nswnuw(i8 %x) { +; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_xor_0_nswnuw +; CHECK-SAME: (i8 [[X:%.*]]) { +; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[X]], 31 +; CHECK-NEXT: [[R:%.*]] = add i8 [[TMP1]], 96 +; CHECK-NEXT: ret i8 [[R]] +; + %a = add nsw nuw i8 %x, 96 ; 01100000 + %r = xor i8 %a, 31 ; 00011111 + ret i8 %r +} + define <2 x i32> @canonicalize_logic_first_xor_vector0(<2 x i32> %x) { ; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_xor_vector0 ; CHECK-SAME: (<2 x i32> [[X:%.*]]) { @@ -4543,7 +4686,30 @@ ret <2 x i32> %r } -; elementwise these constants do obey constraints required to canonicalize +define <2 x i32> @canonicalize_logic_first_xor_vector0_nsw(<2 x i32> %x) { +; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_xor_vector0_nsw +; CHECK-SAME: (<2 x i32> [[X:%.*]]) { +; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i32> [[X]], +; CHECK-NEXT: [[R:%.*]] = add <2 x i32> [[TMP1]], +; CHECK-NEXT: ret <2 x i32> [[R]] +; + %a = add nsw <2 x i32> , %x ; <0xFF800000, 0xFF800000> + %r = xor <2 x i32> , %a ; <0x0000800F, 0x0000800F> + ret <2 x i32> %r +} + +define <2 x i32> @canonicalize_logic_first_xor_vector0_nswnuw(<2 x i32> %x) { +; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_xor_vector0_nswnuw +; CHECK-SAME: (<2 x i32> [[X:%.*]]) { +; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i32> [[X]], +; CHECK-NEXT: [[R:%.*]] = add <2 x i32> [[TMP1]], +; CHECK-NEXT: ret <2 x i32> [[R]] +; + %a = add nsw nuw <2 x i32> , %x ; <0xFF800000, 0xFF800000> + %r = xor <2 x i32> , %a ; <0x0000800F, 0x0000800F> + ret <2 x i32> %r +} + define <2 x i32> @canonicalize_logic_first_xor_vector1(<2 x i32> %x) { ; CHECK-LABEL: define {{[^@]+}}@canonicalize_logic_first_xor_vector1 ; CHECK-SAME: (<2 x i32> [[X:%.*]]) {