diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -4285,7 +4285,17 @@ case ISD::UNDEF: return PoisonOnly; - // TODO: ISD::BUILD_VECTOR handling + case ISD::BUILD_VECTOR: + // NOTE: BUILD_VECTOR has implicit truncation of wider scalar elements - + // this shouldn't affect the result. + for (unsigned i = 0, e = Op.getNumOperands(); i < e; ++i) { + if (!DemandedElts[i]) + continue; + if (!isGuaranteedNotToBeUndefOrPoison(Op.getOperand(i), PoisonOnly, + Depth + 1)) + return false; + } + return true; // TODO: Search for noundef attributes from library functions. diff --git a/llvm/test/CodeGen/X86/freeze-constant-fold.ll b/llvm/test/CodeGen/X86/freeze-constant-fold.ll --- a/llvm/test/CodeGen/X86/freeze-constant-fold.ll +++ b/llvm/test/CodeGen/X86/freeze-constant-fold.ll @@ -15,7 +15,6 @@ ret i32 %5 } -; FIXME: X86 scalarization sees through the freeze, but vector types don't. define <4 x i32> @fold_add_freeze_v4i32() { ; X86-LABEL: fold_add_freeze_v4i32: ; X86: # %bb.0: @@ -28,9 +27,7 @@ ; ; X64-LABEL: fold_add_freeze_v4i32: ; X64: # %bb.0: -; X64-NEXT: pxor %xmm1, %xmm1 ; X64-NEXT: pcmpeqd %xmm0, %xmm0 -; X64-NEXT: paddd %xmm1, %xmm0 ; X64-NEXT: retq %1 = insertelement <4 x i32> poison, i32 0, i32 0 %2 = shufflevector <4 x i32> %1, <4 x i32> poison, <4 x i32> zeroinitializer diff --git a/llvm/test/CodeGen/X86/freeze-legalize.ll b/llvm/test/CodeGen/X86/freeze-legalize.ll --- a/llvm/test/CodeGen/X86/freeze-legalize.ll +++ b/llvm/test/CodeGen/X86/freeze-legalize.ll @@ -46,7 +46,7 @@ define <2 x i10> @promote_vec() { ; CHECK-LABEL: promote_vec: ; CHECK: ## %bb.0: -; CHECK-NEXT: movw $1674, %ax ## imm = 0x68A +; CHECK-NEXT: movw $650, %ax ## imm = 0x28A ; CHECK-NEXT: movw $518, %dx ## imm = 0x206 ; CHECK-NEXT: retl %a = freeze <2 x i10>