diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -11843,6 +11843,10 @@ EVT VT = N->getValueType(0); SDLoc DL(N); + // sext(undef) = 0 because the top bit will all be the same. + if (N0.isUndef()) + return DAG.getConstant(0, DL, VT); + if (SDValue Res = tryToFoldExtendOfConstant(N, TLI, DAG, LegalTypes)) return Res; @@ -12088,6 +12092,10 @@ SDValue N0 = N->getOperand(0); EVT VT = N->getValueType(0); + // zext(undef) = 0 + if (N0.isUndef()) + return DAG.getConstant(0, SDLoc(N), VT); + if (SDValue Res = tryToFoldExtendOfConstant(N, TLI, DAG, LegalTypes)) return Res; @@ -12347,6 +12355,10 @@ SDValue N0 = N->getOperand(0); EVT VT = N->getValueType(0); + // aext(undef) = undef + if (N0.isUndef()) + return DAG.getUNDEF(VT); + if (SDValue Res = tryToFoldExtendOfConstant(N, TLI, DAG, LegalTypes)) return Res; diff --git a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.class.ll b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.class.ll --- a/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.class.ll +++ b/llvm/test/CodeGen/AMDGPU/llvm.amdgcn.class.ll @@ -495,11 +495,11 @@ ret void } -; FIXME: Why is the extension still here? ; SI-LABEL: {{^}}test_class_undef_f32: ; SI-NOT: v_cmp_class -; SI: v_cndmask_b32_e64 v{{[0-9]+}}, 0, -1, -; SI: buffer_store_dword +; SI: v_mov_b32_e32 [[RESULT:v[0-9]+]], 0 +; SI: buffer_store_dword [[RESULT]] +; SI: s_endpgm define amdgpu_kernel void @test_class_undef_f32(i32 addrspace(1)* %out, float %a, i32 %b) #0 { %result = call i1 @llvm.amdgcn.class.f32(float undef, i32 %b) #1 %sext = sext i1 %result to i32 diff --git a/llvm/test/CodeGen/RISCV/min-max.ll b/llvm/test/CodeGen/RISCV/min-max.ll --- a/llvm/test/CodeGen/RISCV/min-max.ll +++ b/llvm/test/CodeGen/RISCV/min-max.ll @@ -531,52 +531,91 @@ } ; Tests with undef operands. These should fold to undef for RV32 or 0 for RV64. -; FIXME: The RV64 cases are hitting pr55178. define signext i32 @smin_undef_i32() { -; NOZBB-LABEL: smin_undef_i32: -; NOZBB: # %bb.0: -; NOZBB-NEXT: ret +; RV32I-LABEL: smin_undef_i32: +; RV32I: # %bb.0: +; RV32I-NEXT: ret ; -; ZBB-LABEL: smin_undef_i32: -; ZBB: # %bb.0: -; ZBB-NEXT: ret +; RV64I-LABEL: smin_undef_i32: +; RV64I: # %bb.0: +; RV64I-NEXT: li a0, 0 +; RV64I-NEXT: ret +; +; RV32ZBB-LABEL: smin_undef_i32: +; RV32ZBB: # %bb.0: +; RV32ZBB-NEXT: ret +; +; RV64ZBB-LABEL: smin_undef_i32: +; RV64ZBB: # %bb.0: +; RV64ZBB-NEXT: li a0, 0 +; RV64ZBB-NEXT: ret %c = call i32 @llvm.smin.i32(i32 undef, i32 undef) ret i32 %c } define signext i32 @smax_undef_i32() { -; NOZBB-LABEL: smax_undef_i32: -; NOZBB: # %bb.0: -; NOZBB-NEXT: ret +; RV32I-LABEL: smax_undef_i32: +; RV32I: # %bb.0: +; RV32I-NEXT: ret ; -; ZBB-LABEL: smax_undef_i32: -; ZBB: # %bb.0: -; ZBB-NEXT: ret +; RV64I-LABEL: smax_undef_i32: +; RV64I: # %bb.0: +; RV64I-NEXT: li a0, 0 +; RV64I-NEXT: ret +; +; RV32ZBB-LABEL: smax_undef_i32: +; RV32ZBB: # %bb.0: +; RV32ZBB-NEXT: ret +; +; RV64ZBB-LABEL: smax_undef_i32: +; RV64ZBB: # %bb.0: +; RV64ZBB-NEXT: li a0, 0 +; RV64ZBB-NEXT: ret %c = call i32 @llvm.smax.i32(i32 undef, i32 undef) ret i32 %c } define signext i32 @umin_undef_i32() { -; NOZBB-LABEL: umin_undef_i32: -; NOZBB: # %bb.0: -; NOZBB-NEXT: ret +; RV32I-LABEL: umin_undef_i32: +; RV32I: # %bb.0: +; RV32I-NEXT: ret ; -; ZBB-LABEL: umin_undef_i32: -; ZBB: # %bb.0: -; ZBB-NEXT: ret +; RV64I-LABEL: umin_undef_i32: +; RV64I: # %bb.0: +; RV64I-NEXT: li a0, 0 +; RV64I-NEXT: ret +; +; RV32ZBB-LABEL: umin_undef_i32: +; RV32ZBB: # %bb.0: +; RV32ZBB-NEXT: ret +; +; RV64ZBB-LABEL: umin_undef_i32: +; RV64ZBB: # %bb.0: +; RV64ZBB-NEXT: li a0, 0 +; RV64ZBB-NEXT: ret %c = call i32 @llvm.umin.i32(i32 undef, i32 undef) ret i32 %c } define signext i32 @umax_undef_i32() { -; NOZBB-LABEL: umax_undef_i32: -; NOZBB: # %bb.0: -; NOZBB-NEXT: ret +; RV32I-LABEL: umax_undef_i32: +; RV32I: # %bb.0: +; RV32I-NEXT: ret ; -; ZBB-LABEL: umax_undef_i32: -; ZBB: # %bb.0: -; ZBB-NEXT: ret +; RV64I-LABEL: umax_undef_i32: +; RV64I: # %bb.0: +; RV64I-NEXT: li a0, 0 +; RV64I-NEXT: ret +; +; RV32ZBB-LABEL: umax_undef_i32: +; RV32ZBB: # %bb.0: +; RV32ZBB-NEXT: ret +; +; RV64ZBB-LABEL: umax_undef_i32: +; RV64ZBB: # %bb.0: +; RV64ZBB-NEXT: li a0, 0 +; RV64ZBB-NEXT: ret %c = call i32 @llvm.umax.i32(i32 undef, i32 undef) ret i32 %c }