diff options
Diffstat (limited to 'llvm/test')
| -rw-r--r-- | llvm/test/Transforms/InstCombine/and-xor-or.ll | 244 |
1 files changed, 234 insertions, 10 deletions
diff --git a/llvm/test/Transforms/InstCombine/and-xor-or.ll b/llvm/test/Transforms/InstCombine/and-xor-or.ll index ec36d13ec1a..e4495fa5b0a 100644 --- a/llvm/test/Transforms/InstCombine/and-xor-or.ll +++ b/llvm/test/Transforms/InstCombine/and-xor-or.ll @@ -1,24 +1,248 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt < %s -instcombine -S | FileCheck %s ; rdar://10770603 -; (x & y) | (x ^ y) -> x | y -define i64 @or(i64 %x, i64 %y) nounwind uwtable readnone ssp { +; (x & y) | (x ^ y) -> x | y + +define i64 @or(i64 %x, i64 %y) { +; CHECK-LABEL: @or( +; CHECK-NEXT: [[TMP1:%.*]] = or i64 [[Y:%.*]], [[X:%.*]] +; CHECK-NEXT: ret i64 [[TMP1]] +; %1 = and i64 %y, %x %2 = xor i64 %y, %x %3 = add i64 %1, %2 ret i64 %3 -; CHECK-LABEL: @or( -; CHECK: or i64 -; CHECK-NEXT: ret } -; (x & y) + (x ^ y) -> x | y -define i64 @or2(i64 %x, i64 %y) nounwind uwtable readnone ssp { +; (x & y) + (x ^ y) -> x | y + +define i64 @or2(i64 %x, i64 %y) { +; CHECK-LABEL: @or2( +; CHECK-NEXT: [[TMP1:%.*]] = or i64 [[Y:%.*]], [[X:%.*]] +; CHECK-NEXT: ret i64 [[TMP1]] +; %1 = and i64 %y, %x %2 = xor i64 %y, %x %3 = or i64 %1, %2 ret i64 %3 -; CHECK-LABEL: @or2( -; CHECK: or i64 -; CHECK-NEXT: ret } + +; PR37098 - https://bugs.llvm.org/show_bug.cgi?id=37098 +; Reassociate bitwise logic to eliminate a shift. +; There are 4 commuted * 3 shift ops * 3 logic ops = 36 potential variations of this fold. +; Mix the commutation options to provide coverage using less tests. + +define i8 @and_shl(i8 %x, i8 %y, i8 %z, i8 %shamt) { +; CHECK-LABEL: @and_shl( +; CHECK-NEXT: [[SX:%.*]] = shl i8 [[X:%.*]], [[SHAMT:%.*]] +; CHECK-NEXT: [[SY:%.*]] = shl i8 [[Y:%.*]], [[SHAMT]] +; CHECK-NEXT: [[A:%.*]] = and i8 [[SX]], [[Z:%.*]] +; CHECK-NEXT: [[R:%.*]] = and i8 [[SY]], [[A]] +; CHECK-NEXT: ret i8 [[R]] +; + %sx = shl i8 %x, %shamt + %sy = shl i8 %y, %shamt + %a = and i8 %sx, %z + %r = and i8 %sy, %a + ret i8 %r +} + +define i8 @or_shl(i8 %x, i8 %y, i8 %z, i8 %shamt) { +; CHECK-LABEL: @or_shl( +; CHECK-NEXT: [[SX:%.*]] = shl i8 [[X:%.*]], [[SHAMT:%.*]] +; CHECK-NEXT: [[SY:%.*]] = shl i8 [[Y:%.*]], [[SHAMT]] +; CHECK-NEXT: [[A:%.*]] = or i8 [[SX]], [[Z:%.*]] +; CHECK-NEXT: [[R:%.*]] = or i8 [[A]], [[SY]] +; CHECK-NEXT: ret i8 [[R]] +; + %sx = shl i8 %x, %shamt + %sy = shl i8 %y, %shamt + %a = or i8 %sx, %z + %r = or i8 %a, %sy + ret i8 %r +} + +define i8 @xor_shl(i8 %x, i8 %y, i8 %zarg, i8 %shamt) { +; CHECK-LABEL: @xor_shl( +; CHECK-NEXT: [[Z:%.*]] = sdiv i8 42, [[ZARG:%.*]] +; CHECK-NEXT: [[SX:%.*]] = shl i8 [[X:%.*]], [[SHAMT:%.*]] +; CHECK-NEXT: [[SY:%.*]] = shl i8 [[Y:%.*]], [[SHAMT]] +; CHECK-NEXT: [[A:%.*]] = xor i8 [[Z]], [[SX]] +; CHECK-NEXT: [[R:%.*]] = xor i8 [[A]], [[SY]] +; CHECK-NEXT: ret i8 [[R]] +; + %z = sdiv i8 42, %zarg ; thwart complexity-based canonicalization + %sx = shl i8 %x, %shamt + %sy = shl i8 %y, %shamt + %a = xor i8 %z, %sx + %r = xor i8 %a, %sy + ret i8 %r +} + +define i8 @and_lshr(i8 %x, i8 %y, i8 %zarg, i8 %shamt) { +; CHECK-LABEL: @and_lshr( +; CHECK-NEXT: [[Z:%.*]] = sdiv i8 42, [[ZARG:%.*]] +; CHECK-NEXT: [[SX:%.*]] = lshr i8 [[X:%.*]], [[SHAMT:%.*]] +; CHECK-NEXT: [[SY:%.*]] = lshr i8 [[Y:%.*]], [[SHAMT]] +; CHECK-NEXT: [[A:%.*]] = and i8 [[Z]], [[SX]] +; CHECK-NEXT: [[R:%.*]] = and i8 [[SY]], [[A]] +; CHECK-NEXT: ret i8 [[R]] +; + %z = sdiv i8 42, %zarg ; thwart complexity-based canonicalization + %sx = lshr i8 %x, %shamt + %sy = lshr i8 %y, %shamt + %a = and i8 %z, %sx + %r = and i8 %sy, %a + ret i8 %r +} + +define i8 @or_lshr(i8 %x, i8 %y, i8 %z, i8 %shamt) { +; CHECK-LABEL: @or_lshr( +; CHECK-NEXT: [[SX:%.*]] = lshr i8 [[X:%.*]], [[SHAMT:%.*]] +; CHECK-NEXT: [[SY:%.*]] = lshr i8 [[Y:%.*]], [[SHAMT]] +; CHECK-NEXT: [[A:%.*]] = or i8 [[SX]], [[Z:%.*]] +; CHECK-NEXT: [[R:%.*]] = or i8 [[SY]], [[A]] +; CHECK-NEXT: ret i8 [[R]] +; + %sx = lshr i8 %x, %shamt + %sy = lshr i8 %y, %shamt + %a = or i8 %sx, %z + %r = or i8 %sy, %a + ret i8 %r +} + +define i8 @xor_lshr(i8 %x, i8 %y, i8 %z, i8 %shamt) { +; CHECK-LABEL: @xor_lshr( +; CHECK-NEXT: [[SX:%.*]] = lshr i8 [[X:%.*]], [[SHAMT:%.*]] +; CHECK-NEXT: [[SY:%.*]] = lshr i8 [[Y:%.*]], [[SHAMT]] +; CHECK-NEXT: [[A:%.*]] = xor i8 [[SX]], [[Z:%.*]] +; CHECK-NEXT: [[R:%.*]] = xor i8 [[A]], [[SY]] +; CHECK-NEXT: ret i8 [[R]] +; + %sx = lshr i8 %x, %shamt + %sy = lshr i8 %y, %shamt + %a = xor i8 %sx, %z + %r = xor i8 %a, %sy + ret i8 %r +} + +define i8 @and_ashr(i8 %x, i8 %y, i8 %zarg, i8 %shamt) { +; CHECK-LABEL: @and_ashr( +; CHECK-NEXT: [[Z:%.*]] = sdiv i8 42, [[ZARG:%.*]] +; CHECK-NEXT: [[SX:%.*]] = ashr i8 [[X:%.*]], [[SHAMT:%.*]] +; CHECK-NEXT: [[SY:%.*]] = ashr i8 [[Y:%.*]], [[SHAMT]] +; CHECK-NEXT: [[A:%.*]] = and i8 [[Z]], [[SX]] +; CHECK-NEXT: [[R:%.*]] = and i8 [[A]], [[SY]] +; CHECK-NEXT: ret i8 [[R]] +; + %z = sdiv i8 42, %zarg ; thwart complexity-based canonicalization + %sx = ashr i8 %x, %shamt + %sy = ashr i8 %y, %shamt + %a = and i8 %z, %sx + %r = and i8 %a, %sy + ret i8 %r +} + +define i8 @or_ashr(i8 %x, i8 %y, i8 %zarg, i8 %shamt) { +; CHECK-LABEL: @or_ashr( +; CHECK-NEXT: [[Z:%.*]] = sdiv i8 42, [[ZARG:%.*]] +; CHECK-NEXT: [[SX:%.*]] = ashr i8 [[X:%.*]], [[SHAMT:%.*]] +; CHECK-NEXT: [[SY:%.*]] = ashr i8 [[Y:%.*]], [[SHAMT]] +; CHECK-NEXT: [[A:%.*]] = or i8 [[Z]], [[SX]] +; CHECK-NEXT: [[R:%.*]] = or i8 [[SY]], [[A]] +; CHECK-NEXT: ret i8 [[R]] +; + %z = sdiv i8 42, %zarg ; thwart complexity-based canonicalization + %sx = ashr i8 %x, %shamt + %sy = ashr i8 %y, %shamt + %a = or i8 %z, %sx + %r = or i8 %sy, %a + ret i8 %r +} + +define <2 x i8> @xor_ashr(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z, <2 x i8> %shamt) { +; CHECK-LABEL: @xor_ashr( +; CHECK-NEXT: [[SX:%.*]] = ashr <2 x i8> [[X:%.*]], [[SHAMT:%.*]] +; CHECK-NEXT: [[SY:%.*]] = ashr <2 x i8> [[Y:%.*]], [[SHAMT]] +; CHECK-NEXT: [[A:%.*]] = xor <2 x i8> [[SX]], [[Z:%.*]] +; CHECK-NEXT: [[R:%.*]] = xor <2 x i8> [[A]], [[SY]] +; CHECK-NEXT: ret <2 x i8> [[R]] +; + %sx = ashr <2 x i8> %x, %shamt + %sy = ashr <2 x i8> %y, %shamt + %a = xor <2 x i8> %sx, %z + %r = xor <2 x i8> %a, %sy + ret <2 x i8> %r +} + +; Negative test - different logic ops + +define i8 @or_and_shl(i8 %x, i8 %y, i8 %z, i8 %shamt) { +; CHECK-LABEL: @or_and_shl( +; CHECK-NEXT: [[SX:%.*]] = shl i8 [[X:%.*]], [[SHAMT:%.*]] +; CHECK-NEXT: [[SY:%.*]] = shl i8 [[Y:%.*]], [[SHAMT]] +; CHECK-NEXT: [[A:%.*]] = or i8 [[SX]], [[Z:%.*]] +; CHECK-NEXT: [[R:%.*]] = and i8 [[SY]], [[A]] +; CHECK-NEXT: ret i8 [[R]] +; + %sx = shl i8 %x, %shamt + %sy = shl i8 %y, %shamt + %a = or i8 %sx, %z + %r = and i8 %sy, %a + ret i8 %r +} + +; Negative test - different shift ops + +define i8 @or_lshr_shl(i8 %x, i8 %y, i8 %z, i8 %shamt) { +; CHECK-LABEL: @or_lshr_shl( +; CHECK-NEXT: [[SX:%.*]] = lshr i8 [[X:%.*]], [[SHAMT:%.*]] +; CHECK-NEXT: [[SY:%.*]] = shl i8 [[Y:%.*]], [[SHAMT]] +; CHECK-NEXT: [[A:%.*]] = or i8 [[SX]], [[Z:%.*]] +; CHECK-NEXT: [[R:%.*]] = or i8 [[A]], [[SY]] +; CHECK-NEXT: ret i8 [[R]] +; + %sx = lshr i8 %x, %shamt + %sy = shl i8 %y, %shamt + %a = or i8 %sx, %z + %r = or i8 %a, %sy + ret i8 %r +} + +; Negative test - different shift amounts + +define i8 @or_lshr_shamt2(i8 %x, i8 %y, i8 %z, i8 %shamt) { +; CHECK-LABEL: @or_lshr_shamt2( +; CHECK-NEXT: [[SX:%.*]] = lshr i8 [[X:%.*]], 5 +; CHECK-NEXT: [[SY:%.*]] = lshr i8 [[Y:%.*]], [[SHAMT:%.*]] +; CHECK-NEXT: [[A:%.*]] = or i8 [[SX]], [[Z:%.*]] +; CHECK-NEXT: [[R:%.*]] = or i8 [[SY]], [[A]] +; CHECK-NEXT: ret i8 [[R]] +; + %sx = lshr i8 %x, 5 + %sy = lshr i8 %y, %shamt + %a = or i8 %sx, %z + %r = or i8 %sy, %a + ret i8 %r +} + +; Negative test - multi-use + +define i8 @xor_lshr_multiuse(i8 %x, i8 %y, i8 %z, i8 %shamt) { +; CHECK-LABEL: @xor_lshr_multiuse( +; CHECK-NEXT: [[SX:%.*]] = lshr i8 [[X:%.*]], [[SHAMT:%.*]] +; CHECK-NEXT: [[SY:%.*]] = lshr i8 [[Y:%.*]], [[SHAMT]] +; CHECK-NEXT: [[A:%.*]] = xor i8 [[SX]], [[Z:%.*]] +; CHECK-NEXT: [[R:%.*]] = xor i8 [[A]], [[SY]] +; CHECK-NEXT: [[R2:%.*]] = sdiv i8 [[A]], [[R]] +; CHECK-NEXT: ret i8 [[R2]] +; + %sx = lshr i8 %x, %shamt + %sy = lshr i8 %y, %shamt + %a = xor i8 %sx, %z + %r = xor i8 %a, %sy + %r2 = sdiv i8 %a, %r + ret i8 %r2 +} + |

