mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
[ConstantFolding] improve folding of binops with vector undef operand
A non-undef operand may still have undef constant elements, so we should always propagate the vector results per-lane. llvm-svn: 340194
This commit is contained in:
parent
8e1b93caef
commit
c684399bd3
@ -916,13 +916,14 @@ Constant *llvm::ConstantFoldInsertValueInstruction(Constant *Agg,
|
||||
return ConstantVector::get(Result);
|
||||
}
|
||||
|
||||
|
||||
Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode,
|
||||
Constant *C1, Constant *C2) {
|
||||
Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, Constant *C1,
|
||||
Constant *C2) {
|
||||
assert(Instruction::isBinaryOp(Opcode) && "Non-binary instruction detected");
|
||||
|
||||
// Handle UndefValue up front.
|
||||
if (isa<UndefValue>(C1) || isa<UndefValue>(C2)) {
|
||||
// Handle scalar UndefValue. Vectors are always evaluated per element.
|
||||
bool HasScalarUndef = !C1->getType()->isVectorTy() &&
|
||||
(isa<UndefValue>(C1) || isa<UndefValue>(C2));
|
||||
if (HasScalarUndef) {
|
||||
switch (static_cast<Instruction::BinaryOps>(Opcode)) {
|
||||
case Instruction::Xor:
|
||||
if (isa<UndefValue>(C1) && isa<UndefValue>(C2))
|
||||
@ -1024,9 +1025,8 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode,
|
||||
}
|
||||
}
|
||||
|
||||
// At this point neither constant should be an UndefValue.
|
||||
assert(!isa<UndefValue>(C1) && !isa<UndefValue>(C2) &&
|
||||
"Unexpected UndefValue");
|
||||
// Neither constant should be UndefValue, unless these are vector constants.
|
||||
assert(!HasScalarUndef && "Unexpected UndefValue");
|
||||
|
||||
// Handle simplifications when the RHS is a constant int.
|
||||
if (ConstantInt *CI2 = dyn_cast<ConstantInt>(C2)) {
|
||||
@ -1218,7 +1218,7 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode,
|
||||
}
|
||||
}
|
||||
} else if (VectorType *VTy = dyn_cast<VectorType>(C1->getType())) {
|
||||
// Perform elementwise folding.
|
||||
// Fold each element and create a vector constant from those constants.
|
||||
SmallVector<Constant*, 16> Result;
|
||||
Type *Ty = IntegerType::get(VTy->getContext(), 32);
|
||||
for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) {
|
||||
|
@ -1,11 +1,11 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
||||
; RUN: opt < %s -constprop -S -o - | FileCheck %s
|
||||
|
||||
; FIXME: When both operands are undef in a lane, that lane should produce an undef result.
|
||||
; When both operands are undef in a lane, that lane should produce an undef result.
|
||||
|
||||
define <3 x i8> @shl() {
|
||||
; CHECK-LABEL: @shl(
|
||||
; CHECK-NEXT: ret <3 x i8> zeroinitializer
|
||||
; CHECK-NEXT: ret <3 x i8> <i8 undef, i8 0, i8 0>
|
||||
;
|
||||
%c = shl <3 x i8> undef, <i8 undef, i8 4, i8 1>
|
||||
ret <3 x i8> %c
|
||||
@ -13,7 +13,7 @@ define <3 x i8> @shl() {
|
||||
|
||||
define <3 x i8> @and() {
|
||||
; CHECK-LABEL: @and(
|
||||
; CHECK-NEXT: ret <3 x i8> zeroinitializer
|
||||
; CHECK-NEXT: ret <3 x i8> <i8 undef, i8 0, i8 undef>
|
||||
;
|
||||
%c = and <3 x i8> <i8 undef, i8 42, i8 undef>, undef
|
||||
ret <3 x i8> %c
|
||||
@ -21,7 +21,7 @@ define <3 x i8> @and() {
|
||||
|
||||
define <3 x i8> @and_commute() {
|
||||
; CHECK-LABEL: @and_commute(
|
||||
; CHECK-NEXT: ret <3 x i8> zeroinitializer
|
||||
; CHECK-NEXT: ret <3 x i8> <i8 0, i8 0, i8 undef>
|
||||
;
|
||||
%c = and <3 x i8> undef, <i8 -42, i8 42, i8 undef>
|
||||
ret <3 x i8> %c
|
||||
@ -29,7 +29,7 @@ define <3 x i8> @and_commute() {
|
||||
|
||||
define <3 x i8> @or() {
|
||||
; CHECK-LABEL: @or(
|
||||
; CHECK-NEXT: ret <3 x i8> <i8 -1, i8 -1, i8 -1>
|
||||
; CHECK-NEXT: ret <3 x i8> <i8 undef, i8 -1, i8 undef>
|
||||
;
|
||||
%c = or <3 x i8> <i8 undef, i8 42, i8 undef>, undef
|
||||
ret <3 x i8> %c
|
||||
@ -37,7 +37,7 @@ define <3 x i8> @or() {
|
||||
|
||||
define <3 x i8> @or_commute() {
|
||||
; CHECK-LABEL: @or_commute(
|
||||
; CHECK-NEXT: ret <3 x i8> <i8 -1, i8 -1, i8 -1>
|
||||
; CHECK-NEXT: ret <3 x i8> <i8 -1, i8 -1, i8 undef>
|
||||
;
|
||||
%c = or <3 x i8> undef, <i8 -42, i8 42, i8 undef>
|
||||
ret <3 x i8> %c
|
||||
@ -45,7 +45,7 @@ define <3 x i8> @or_commute() {
|
||||
|
||||
define <3 x float> @fadd() {
|
||||
; CHECK-LABEL: @fadd(
|
||||
; CHECK-NEXT: ret <3 x float> <float 0x7FF8000000000000, float 0x7FF8000000000000, float 0x7FF8000000000000>
|
||||
; CHECK-NEXT: ret <3 x float> <float undef, float 0x7FF8000000000000, float undef>
|
||||
;
|
||||
%c = fadd <3 x float> <float undef, float 42.0, float undef>, undef
|
||||
ret <3 x float> %c
|
||||
@ -53,7 +53,7 @@ define <3 x float> @fadd() {
|
||||
|
||||
define <3 x float> @fadd_commute() {
|
||||
; CHECK-LABEL: @fadd_commute(
|
||||
; CHECK-NEXT: ret <3 x float> <float 0x7FF8000000000000, float 0x7FF8000000000000, float 0x7FF8000000000000>
|
||||
; CHECK-NEXT: ret <3 x float> <float 0x7FF8000000000000, float 0x7FF8000000000000, float undef>
|
||||
;
|
||||
%c = fadd <3 x float> undef, <float -42.0, float 42.0, float undef>
|
||||
ret <3 x float> %c
|
||||
|
Loading…
x
Reference in New Issue
Block a user