Author: Amr Hesham Date: 2026-02-24T19:50:35+01:00 New Revision: ab14dab5ec4c7159ed439e1735bdb1455fd4b785
URL: https://github.com/llvm/llvm-project/commit/ab14dab5ec4c7159ed439e1735bdb1455fd4b785 DIFF: https://github.com/llvm/llvm-project/commit/ab14dab5ec4c7159ed439e1735bdb1455fd4b785.diff LOG: [CIR] Fix Codegen for Vector logical op with FP (#182761) Previously, we perform nq comparison between LHS, RHS, and zero attr with the type of the logical Op, but in the case of a vector with FP element type, the verifier will fail because we perform a comparison of a vector of FP and a vector of int (the result type of the logical op in this case is vector of int) Added: Modified: clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp clang/test/CIR/CodeGen/vector-ext.cpp clang/test/CIR/CodeGen/vector.cpp Removed: ################################################################################ diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp index 7fe7fa347cd03..7ffaa84171bce 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp @@ -1287,17 +1287,18 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> { mlir::Value VisitBinLAnd(const clang::BinaryOperator *e) { if (e->getType()->isVectorType()) { mlir::Location loc = cgf.getLoc(e->getExprLoc()); - mlir::Type vecTy = cgf.convertType(e->getType()); - mlir::Value zeroVec = builder.getNullValue(vecTy, loc); + mlir::Type lhsTy = cgf.convertType(e->getLHS()->getType()); + mlir::Value zeroVec = builder.getNullValue(lhsTy, loc); mlir::Value lhs = Visit(e->getLHS()); mlir::Value rhs = Visit(e->getRHS()); auto cmpOpKind = cir::CmpOpKind::ne; - lhs = cir::VecCmpOp::create(builder, loc, vecTy, cmpOpKind, lhs, zeroVec); - rhs = cir::VecCmpOp::create(builder, loc, vecTy, cmpOpKind, rhs, zeroVec); + mlir::Type resTy = cgf.convertType(e->getType()); + lhs = cir::VecCmpOp::create(builder, loc, resTy, cmpOpKind, lhs, zeroVec); + rhs = cir::VecCmpOp::create(builder, loc, resTy, cmpOpKind, rhs, zeroVec); mlir::Value vecOr = builder.createAnd(loc, lhs, rhs); - return builder.createIntCast(vecOr, vecTy); + return builder.createIntCast(vecOr, resTy); } assert(!cir::MissingFeatures::instrumentation()); @@ -1335,17 +1336,18 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> { mlir::Value VisitBinLOr(const clang::BinaryOperator *e) { if (e->getType()->isVectorType()) { mlir::Location loc = cgf.getLoc(e->getExprLoc()); - mlir::Type vecTy = cgf.convertType(e->getType()); - mlir::Value zeroVec = builder.getNullValue(vecTy, loc); + mlir::Type lhsTy = cgf.convertType(e->getLHS()->getType()); + mlir::Value zeroVec = builder.getNullValue(lhsTy, loc); mlir::Value lhs = Visit(e->getLHS()); mlir::Value rhs = Visit(e->getRHS()); auto cmpOpKind = cir::CmpOpKind::ne; - lhs = cir::VecCmpOp::create(builder, loc, vecTy, cmpOpKind, lhs, zeroVec); - rhs = cir::VecCmpOp::create(builder, loc, vecTy, cmpOpKind, rhs, zeroVec); + mlir::Type resTy = cgf.convertType(e->getType()); + lhs = cir::VecCmpOp::create(builder, loc, resTy, cmpOpKind, lhs, zeroVec); + rhs = cir::VecCmpOp::create(builder, loc, resTy, cmpOpKind, rhs, zeroVec); mlir::Value vecOr = builder.createOr(loc, lhs, rhs); - return builder.createIntCast(vecOr, vecTy); + return builder.createIntCast(vecOr, resTy); } assert(!cir::MissingFeatures::instrumentation()); diff --git a/clang/test/CIR/CodeGen/vector-ext.cpp b/clang/test/CIR/CodeGen/vector-ext.cpp index 4d04d4f2f3311..ce10e314015d5 100644 --- a/clang/test/CIR/CodeGen/vector-ext.cpp +++ b/clang/test/CIR/CodeGen/vector-ext.cpp @@ -1218,6 +1218,46 @@ void logical_or_vi4() { // OGCG: %[[RESULT:.*]] = sext <4 x i1> %[[VEC_OR]] to <4 x i32> // OGCG: store <4 x i32> %[[RESULT]], ptr %[[C_ADDR]], align 16 +void logical_or_vf4() { + vf4 a; + vf4 b; + vi4 c = a || b; +} + +// CIR: %[[A_ADDR:.*]] = cir.alloca !cir.vector<4 x !cir.float>, !cir.ptr<!cir.vector<4 x !cir.float>>, ["a"] +// CIR: %[[B_ADDR:.*]] = cir.alloca !cir.vector<4 x !cir.float>, !cir.ptr<!cir.vector<4 x !cir.float>>, ["b"] +// CIR: %[[C_ADDR:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["c", init] +// CIR: %[[ZERO_VEC:.*]] = cir.const #cir.zero : !cir.vector<4 x !cir.float> +// CIR: %[[TMP_A:.*]] = cir.load {{.*}} %[[A_ADDR]] : !cir.ptr<!cir.vector<4 x !cir.float>>, !cir.vector<4 x !cir.float> +// CIR: %[[TMP_B:.*]] = cir.load {{.*}} %[[B_ADDR]] : !cir.ptr<!cir.vector<4 x !cir.float>>, !cir.vector<4 x !cir.float> +// CIR: %[[NE_A_ZERO:.*]] = cir.vec.cmp(ne, %4, %[[ZERO_VEC]]) : !cir.vector<4 x !cir.float>, !cir.vector<4 x !s32i> +// CIR: %[[NE_B_ZERO:.*]] = cir.vec.cmp(ne, %5, %[[ZERO_VEC]]) : !cir.vector<4 x !cir.float>, !cir.vector<4 x !s32i> +// CIR: %[[RESULT:.*]] = cir.binop(or, %[[NE_A_ZERO]], %[[NE_B_ZERO]]) : !cir.vector<4 x !s32i> +// CIR: cir.store {{.*}} %[[RESULT]], %[[C_ADDR]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>> + +// LLVM: %[[A_ADDR:.*]] = alloca <4 x float>, i64 1, align 16 +// LLVM: %[[B_ADDR:.*]] = alloca <4 x float>, i64 1, align 16 +// LLVM: %[[C_ADDR:.*]] = alloca <4 x i32>, i64 1, align 16 +// LLVM: %[[TMP_A:.*]] = load <4 x float>, ptr %[[A_ADDR]], align 16 +// LLVM: %[[TMP_B:.*]] = load <4 x float>, ptr %[[B_ADDR]], align 16 +// LLVM: %[[NE_A_ZERO:.*]] = fcmp une <4 x float> %[[TMP_A]], zeroinitializer +// LLVM: %[[NE_A_ZERO_SEXT:.*]] = sext <4 x i1> %[[NE_A_ZERO]] to <4 x i32> +// LLVM: %[[NE_B_ZERO:.*]] = fcmp une <4 x float> %[[TMP_B]], zeroinitializer +// LLVM: %[[NE_B_ZERO_SEXT:.*]] = sext <4 x i1> %[[NE_B_ZERO]] to <4 x i32> +// LLVM: %[[RESULT:.*]] = or <4 x i32> %[[NE_A_ZERO_SEXT]], %[[NE_B_ZERO_SEXT]] +// LLVM: store <4 x i32> %[[RESULT]], ptr %[[C_ADDR]], align 16 + +// OGCG: %[[A_ADDR:.*]] = alloca <4 x float>, align 16 +// OGCG: %[[B_ADDR:.*]] = alloca <4 x float>, align 16 +// OGCG: %[[C_ADDR:.*]] = alloca <4 x i32>, align 16 +// OGCG: %[[TMP_A:.*]] = load <4 x float>, ptr %[[A_ADDR]], align 16 +// OGCG: %[[TMP_B:.*]] = load <4 x float>, ptr %[[B_ADDR]], align 16 +// OGCG: %[[NE_A_ZERO:.*]] = fcmp une <4 x float> %[[TMP_A]], zeroinitializer +// OGCG: %[[NE_B_ZERO:.*]] = fcmp une <4 x float> %[[TMP_B]], zeroinitializer +// OGCG: %[[RESULT:.*]] = or <4 x i1> %[[NE_A_ZERO]], %[[NE_B_ZERO]] +// OGCG: %[[RESULT_VI4:.*]] = sext <4 x i1> %2 to <4 x i32> +// OGCG: store <4 x i32> %[[RESULT_VI4]], ptr %[[C_ADDR]], align 16 + void foo24() { vh4 a; vh4 b; @@ -1297,6 +1337,46 @@ void logical_and_vi4() { // OGCG: %[[RESULT:.*]] = sext <4 x i1> %[[VEC_OR]] to <4 x i32> // OGCG: store <4 x i32> %[[RESULT]], ptr %[[C_ADDR]], align 16 +void logical_and_vf4() { + vf4 a; + vf4 b; + vi4 c = a && b; +} + +// CIR: %[[A_ADDR:.*]] = cir.alloca !cir.vector<4 x !cir.float>, !cir.ptr<!cir.vector<4 x !cir.float>>, ["a"] +// CIR: %[[B_ADDR:.*]] = cir.alloca !cir.vector<4 x !cir.float>, !cir.ptr<!cir.vector<4 x !cir.float>>, ["b"] +// CIR: %[[C_ADDR:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["c", init] +// CIR: %[[ZERO_VEC:.*]] = cir.const #cir.zero : !cir.vector<4 x !cir.float> +// CIR: %[[TMP_A:.*]] = cir.load {{.*}} %[[A_ADDR]] : !cir.ptr<!cir.vector<4 x !cir.float>>, !cir.vector<4 x !cir.float> +// CIR: %[[TMP_B:.*]] = cir.load {{.*}} %[[B_ADDR]] : !cir.ptr<!cir.vector<4 x !cir.float>>, !cir.vector<4 x !cir.float> +// CIR: %[[NE_A_ZERO:.*]] = cir.vec.cmp(ne, %4, %[[ZERO_VEC]]) : !cir.vector<4 x !cir.float>, !cir.vector<4 x !s32i> +// CIR: %[[NE_B_ZERO:.*]] = cir.vec.cmp(ne, %5, %[[ZERO_VEC]]) : !cir.vector<4 x !cir.float>, !cir.vector<4 x !s32i> +// CIR: %[[RESULT:.*]] = cir.binop(and, %[[NE_A_ZERO]], %[[NE_B_ZERO]]) : !cir.vector<4 x !s32i> +// CIR: cir.store {{.*}} %[[RESULT]], %[[C_ADDR]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>> + +// LLVM: %[[A_ADDR:.*]] = alloca <4 x float>, i64 1, align 16 +// LLVM: %[[B_ADDR:.*]] = alloca <4 x float>, i64 1, align 16 +// LLVM: %[[C_ADDR:.*]] = alloca <4 x i32>, i64 1, align 16 +// LLVM: %[[TMP_A:.*]] = load <4 x float>, ptr %[[A_ADDR]], align 16 +// LLVM: %[[TMP_B:.*]] = load <4 x float>, ptr %[[B_ADDR]], align 16 +// LLVM: %[[NE_A_ZERO:.*]] = fcmp une <4 x float> %[[TMP_A]], zeroinitializer +// LLVM: %[[NE_A_ZERO_SEXT:.*]] = sext <4 x i1> %[[NE_A_ZERO]] to <4 x i32> +// LLVM: %[[NE_B_ZERO:.*]] = fcmp une <4 x float> %[[TMP_B]], zeroinitializer +// LLVM: %[[NE_B_ZERO_SEXT:.*]] = sext <4 x i1> %[[NE_B_ZERO]] to <4 x i32> +// LLVM: %[[RESULT:.*]] = and <4 x i32> %[[NE_A_ZERO_SEXT]], %[[NE_B_ZERO_SEXT]] +// LLVM: store <4 x i32> %[[RESULT]], ptr %[[C_ADDR]], align 16 + +// OGCG: %[[A_ADDR:.*]] = alloca <4 x float>, align 16 +// OGCG: %[[B_ADDR:.*]] = alloca <4 x float>, align 16 +// OGCG: %[[C_ADDR:.*]] = alloca <4 x i32>, align 16 +// OGCG: %[[TMP_A:.*]] = load <4 x float>, ptr %[[A_ADDR]], align 16 +// OGCG: %[[TMP_B:.*]] = load <4 x float>, ptr %[[B_ADDR]], align 16 +// OGCG: %[[NE_A_ZERO:.*]] = fcmp une <4 x float> %[[TMP_A]], zeroinitializer +// OGCG: %[[NE_B_ZERO:.*]] = fcmp une <4 x float> %[[TMP_B]], zeroinitializer +// OGCG: %[[RESULT:.*]] = and <4 x i1> %[[NE_A_ZERO]], %[[NE_B_ZERO]] +// OGCG: %[[RESULT_VI4:.*]] = sext <4 x i1> %2 to <4 x i32> +// OGCG: store <4 x i32> %[[RESULT_VI4]], ptr %[[C_ADDR]], align 16 + void logical_not() { vi4 a; vi4 b = !a; diff --git a/clang/test/CIR/CodeGen/vector.cpp b/clang/test/CIR/CodeGen/vector.cpp index 686af2db41b71..31b056f5e5bb1 100644 --- a/clang/test/CIR/CodeGen/vector.cpp +++ b/clang/test/CIR/CodeGen/vector.cpp @@ -1260,6 +1260,46 @@ void logical_or_vi4() { // OGCG: %[[RESULT:.*]] = sext <4 x i1> %[[VEC_OR]] to <4 x i32> // OGCG: store <4 x i32> %[[RESULT]], ptr %[[C_ADDR]], align 16 +void logical_or_vf4() { + vf4 a; + vf4 b; + vi4 c = a || b; +} + +// CIR: %[[A_ADDR:.*]] = cir.alloca !cir.vector<4 x !cir.float>, !cir.ptr<!cir.vector<4 x !cir.float>>, ["a"] +// CIR: %[[B_ADDR:.*]] = cir.alloca !cir.vector<4 x !cir.float>, !cir.ptr<!cir.vector<4 x !cir.float>>, ["b"] +// CIR: %[[C_ADDR:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["c", init] +// CIR: %[[ZERO_VEC:.*]] = cir.const #cir.zero : !cir.vector<4 x !cir.float> +// CIR: %[[TMP_A:.*]] = cir.load {{.*}} %[[A_ADDR]] : !cir.ptr<!cir.vector<4 x !cir.float>>, !cir.vector<4 x !cir.float> +// CIR: %[[TMP_B:.*]] = cir.load {{.*}} %[[B_ADDR]] : !cir.ptr<!cir.vector<4 x !cir.float>>, !cir.vector<4 x !cir.float> +// CIR: %[[NE_A_ZERO:.*]] = cir.vec.cmp(ne, %4, %[[ZERO_VEC]]) : !cir.vector<4 x !cir.float>, !cir.vector<4 x !s32i> +// CIR: %[[NE_B_ZERO:.*]] = cir.vec.cmp(ne, %5, %[[ZERO_VEC]]) : !cir.vector<4 x !cir.float>, !cir.vector<4 x !s32i> +// CIR: %[[RESULT:.*]] = cir.binop(or, %[[NE_A_ZERO]], %[[NE_B_ZERO]]) : !cir.vector<4 x !s32i> +// CIR: cir.store {{.*}} %[[RESULT]], %[[C_ADDR]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>> + +// LLVM: %[[A_ADDR:.*]] = alloca <4 x float>, i64 1, align 16 +// LLVM: %[[B_ADDR:.*]] = alloca <4 x float>, i64 1, align 16 +// LLVM: %[[C_ADDR:.*]] = alloca <4 x i32>, i64 1, align 16 +// LLVM: %[[TMP_A:.*]] = load <4 x float>, ptr %[[A_ADDR]], align 16 +// LLVM: %[[TMP_B:.*]] = load <4 x float>, ptr %[[B_ADDR]], align 16 +// LLVM: %[[NE_A_ZERO:.*]] = fcmp une <4 x float> %[[TMP_A]], zeroinitializer +// LLVM: %[[NE_A_ZERO_SEXT:.*]] = sext <4 x i1> %[[NE_A_ZERO]] to <4 x i32> +// LLVM: %[[NE_B_ZERO:.*]] = fcmp une <4 x float> %[[TMP_B]], zeroinitializer +// LLVM: %[[NE_B_ZERO_SEXT:.*]] = sext <4 x i1> %[[NE_B_ZERO]] to <4 x i32> +// LLVM: %[[RESULT:.*]] = or <4 x i32> %[[NE_A_ZERO_SEXT]], %[[NE_B_ZERO_SEXT]] +// LLVM: store <4 x i32> %[[RESULT]], ptr %[[C_ADDR]], align 16 + +// OGCG: %[[A_ADDR:.*]] = alloca <4 x float>, align 16 +// OGCG: %[[B_ADDR:.*]] = alloca <4 x float>, align 16 +// OGCG: %[[C_ADDR:.*]] = alloca <4 x i32>, align 16 +// OGCG: %[[TMP_A:.*]] = load <4 x float>, ptr %[[A_ADDR]], align 16 +// OGCG: %[[TMP_B:.*]] = load <4 x float>, ptr %[[B_ADDR]], align 16 +// OGCG: %[[NE_A_ZERO:.*]] = fcmp une <4 x float> %[[TMP_A]], zeroinitializer +// OGCG: %[[NE_B_ZERO:.*]] = fcmp une <4 x float> %[[TMP_B]], zeroinitializer +// OGCG: %[[RESULT:.*]] = or <4 x i1> %[[NE_A_ZERO]], %[[NE_B_ZERO]] +// OGCG: %[[RESULT_VI4:.*]] = sext <4 x i1> %2 to <4 x i32> +// OGCG: store <4 x i32> %[[RESULT_VI4]], ptr %[[C_ADDR]], align 16 + void foo27() { vh4 a; vh4 b; @@ -1339,6 +1379,46 @@ void logical_and_vi4() { // OGCG: %[[RESULT:.*]] = sext <4 x i1> %[[VEC_OR]] to <4 x i32> // OGCG: store <4 x i32> %[[RESULT]], ptr %[[C_ADDR]], align 16 +void logical_and_vf4() { + vf4 a; + vf4 b; + vi4 c = a && b; +} + +// CIR: %[[A_ADDR:.*]] = cir.alloca !cir.vector<4 x !cir.float>, !cir.ptr<!cir.vector<4 x !cir.float>>, ["a"] +// CIR: %[[B_ADDR:.*]] = cir.alloca !cir.vector<4 x !cir.float>, !cir.ptr<!cir.vector<4 x !cir.float>>, ["b"] +// CIR: %[[C_ADDR:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["c", init] +// CIR: %[[ZERO_VEC:.*]] = cir.const #cir.zero : !cir.vector<4 x !cir.float> +// CIR: %[[TMP_A:.*]] = cir.load {{.*}} %[[A_ADDR]] : !cir.ptr<!cir.vector<4 x !cir.float>>, !cir.vector<4 x !cir.float> +// CIR: %[[TMP_B:.*]] = cir.load {{.*}} %[[B_ADDR]] : !cir.ptr<!cir.vector<4 x !cir.float>>, !cir.vector<4 x !cir.float> +// CIR: %[[NE_A_ZERO:.*]] = cir.vec.cmp(ne, %4, %[[ZERO_VEC]]) : !cir.vector<4 x !cir.float>, !cir.vector<4 x !s32i> +// CIR: %[[NE_B_ZERO:.*]] = cir.vec.cmp(ne, %5, %[[ZERO_VEC]]) : !cir.vector<4 x !cir.float>, !cir.vector<4 x !s32i> +// CIR: %[[RESULT:.*]] = cir.binop(and, %[[NE_A_ZERO]], %[[NE_B_ZERO]]) : !cir.vector<4 x !s32i> +// CIR: cir.store {{.*}} %[[RESULT]], %[[C_ADDR]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>> + +// LLVM: %[[A_ADDR:.*]] = alloca <4 x float>, i64 1, align 16 +// LLVM: %[[B_ADDR:.*]] = alloca <4 x float>, i64 1, align 16 +// LLVM: %[[C_ADDR:.*]] = alloca <4 x i32>, i64 1, align 16 +// LLVM: %[[TMP_A:.*]] = load <4 x float>, ptr %[[A_ADDR]], align 16 +// LLVM: %[[TMP_B:.*]] = load <4 x float>, ptr %[[B_ADDR]], align 16 +// LLVM: %[[NE_A_ZERO:.*]] = fcmp une <4 x float> %[[TMP_A]], zeroinitializer +// LLVM: %[[NE_A_ZERO_SEXT:.*]] = sext <4 x i1> %[[NE_A_ZERO]] to <4 x i32> +// LLVM: %[[NE_B_ZERO:.*]] = fcmp une <4 x float> %[[TMP_B]], zeroinitializer +// LLVM: %[[NE_B_ZERO_SEXT:.*]] = sext <4 x i1> %[[NE_B_ZERO]] to <4 x i32> +// LLVM: %[[RESULT:.*]] = and <4 x i32> %[[NE_A_ZERO_SEXT]], %[[NE_B_ZERO_SEXT]] +// LLVM: store <4 x i32> %[[RESULT]], ptr %[[C_ADDR]], align 16 + +// OGCG: %[[A_ADDR:.*]] = alloca <4 x float>, align 16 +// OGCG: %[[B_ADDR:.*]] = alloca <4 x float>, align 16 +// OGCG: %[[C_ADDR:.*]] = alloca <4 x i32>, align 16 +// OGCG: %[[TMP_A:.*]] = load <4 x float>, ptr %[[A_ADDR]], align 16 +// OGCG: %[[TMP_B:.*]] = load <4 x float>, ptr %[[B_ADDR]], align 16 +// OGCG: %[[NE_A_ZERO:.*]] = fcmp une <4 x float> %[[TMP_A]], zeroinitializer +// OGCG: %[[NE_B_ZERO:.*]] = fcmp une <4 x float> %[[TMP_B]], zeroinitializer +// OGCG: %[[RESULT:.*]] = and <4 x i1> %[[NE_A_ZERO]], %[[NE_B_ZERO]] +// OGCG: %[[RESULT_VI4:.*]] = sext <4 x i1> %2 to <4 x i32> +// OGCG: store <4 x i32> %[[RESULT_VI4]], ptr %[[C_ADDR]], align 16 + void logical_not() { vi4 a; vi4 b = !a; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
