forked from OSchip/llvm-project
249 lines
7.4 KiB
LLVM
249 lines
7.4 KiB
LLVM
; 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) {
|
|
; 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
|
|
}
|
|
|
|
; (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
|
|
}
|
|
|
|
; 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
|
|
}
|
|
|