Index: lib/Target/AArch64/AArch64InstrInfo.td =================================================================== --- lib/Target/AArch64/AArch64InstrInfo.td +++ lib/Target/AArch64/AArch64InstrInfo.td @@ -1129,6 +1129,14 @@ (CSINVWr WZR, WZR, (i32 imm:$cc))>; def : Pat<(AArch64csel (i64 0), (i64 -1), (i32 imm:$cc), NZCV), (CSINVXr XZR, XZR, (i32 imm:$cc))>; +def : Pat<(AArch64csel GPR32:$tval, (i32 -1), (i32 imm:$cc), NZCV), + (CSINVWr GPR32:$tval, WZR, (i32 imm:$cc))>; +def : Pat<(AArch64csel GPR64:$tval, (i64 -1), (i32 imm:$cc), NZCV), + (CSINVXr GPR64:$tval, XZR, (i32 imm:$cc))>; +def : Pat<(AArch64csel (i32 -1), GPR32:$fval, (i32 imm:$cc), NZCV), + (CSINVWr GPR32:$fval, WZR, (i32 (inv_cond_XFORM imm:$cc)))>; +def : Pat<(AArch64csel (i64 -1), GPR64:$fval, (i32 imm:$cc), NZCV), + (CSINVXr GPR64:$fval, XZR, (i32 (inv_cond_XFORM imm:$cc)))>; // The inverse of the condition code from the alias instruction is what is used // in the aliased instruction. The parser all ready inverts the condition code Index: test/CodeGen/AArch64/cond-sel.ll =================================================================== --- test/CodeGen/AArch64/cond-sel.ll +++ test/CodeGen/AArch64/cond-sel.ll @@ -135,6 +135,34 @@ ; CHECK: ret } +define void @test_csinv0(i32 %lhs32, i32 %rhs32, i64 %lhs64, i64 %rhs64) minsize { +; CHECK-LABEL: test_csinv0: + + %tst1 = icmp ugt i32 %lhs32, %rhs32 + %val1 = select i1 %tst1, i32 0, i32 -1 + store volatile i32 %val1, i32* @var32 +; CHECK: cmp [[LHS:w[0-9]+]], [[RHS:w[0-9]+]] +; CHECK: csetm {{w[0-9]+}}, ls + + %rhs2 = add i32 %rhs32, 42 + %tst2 = icmp sle i32 %lhs32, %rhs2 + %val2 = select i1 %tst2, i32 -1, i32 %rhs2 + store volatile i32 %val2, i32* @var32 +; CHECK: cmp [[LHS2:w[0-9]+]], [[RHS2:w[0-9]+]] +; CHECK: csinv {{w[0-9]+}}, [[RHS2]], wzr, gt + +; Note that commuting rhs and lhs in the select changes ugt to ule (i.e. hi to ls). + %rhs3 = mul i64 %rhs64, 19 + %tst3 = icmp ugt i64 %lhs64, %rhs3 + %val3 = select i1 %tst3, i64 %rhs3, i64 -1 + store volatile i64 %val3, i64* @var64 +; CHECK: cmp [[LHS3:x[0-9]+]], [[RHS3:x[0-9]+]] +; CHECK: csinv {{x[0-9]+}}, [[RHS3]], xzr, hi + + ret void +; CHECK: ret +} + define void @test_csneg(i32 %lhs32, i32 %rhs32, i64 %lhs64) minsize { ; CHECK-LABEL: test_csneg: Index: test/CodeGen/AArch64/fp16-v4-instructions.ll =================================================================== --- test/CodeGen/AArch64/fp16-v4-instructions.ll +++ test/CodeGen/AArch64/fp16-v4-instructions.ll @@ -277,10 +277,10 @@ ; CHECK-DAG: fcvt ; CHECK-DAG: fcvt ; CHECK-DAG: fcvt -; CHECK-DAG: csel {{.*}}, wzr, ne -; CHECK-DAG: csel {{.*}}, wzr, ne -; CHECK-DAG: csel {{.*}}, wzr, ne -; CHECK-DAG: csel {{.*}}, wzr, ne +; CHECK-DAG: csetm {{.*}}, ne +; CHECK-DAG: csetm {{.*}}, ne +; CHECK-DAG: csetm {{.*}}, ne +; CHECK-DAG: csetm {{.*}}, ne define <4 x i1> @test_fcmp_une(<4 x half> %a, <4 x half> %b) #0 { %1 = fcmp une <4 x half> %a, %b ret <4 x i1> %1 @@ -296,14 +296,14 @@ ; CHECK-DAG: fcvt ; CHECK-DAG: fcvt ; CHECK-DAG: fcvt -; CHECK-DAG: csel {{.*}}, wzr, eq -; CHECK-DAG: csel {{.*}}, wzr, eq -; CHECK-DAG: csel {{.*}}, wzr, eq -; CHECK-DAG: csel {{.*}}, wzr, eq -; CHECK-DAG: csel {{.*}}, vs -; CHECK-DAG: csel {{.*}}, vs -; CHECK-DAG: csel {{.*}}, vs -; CHECK-DAG: csel {{.*}}, vs +; CHECK-DAG: csetm [[REG1:w[0-9]+]], eq +; CHECK-DAG: csetm [[REG2:w[0-9]+]], eq +; CHECK-DAG: csetm [[REG3:w[0-9]+]], eq +; CHECK-DAG: csetm [[REG4:w[0-9]+]], eq +; CHECK-DAG: csinv {{.*}}, [[REG1]], wzr, vc +; CHECK-DAG: csinv {{.*}}, [[REG2]], wzr, vc +; CHECK-DAG: csinv {{.*}}, [[REG3]], wzr, vc +; CHECK-DAG: csinv {{.*}}, [[REG4]], wzr, vc define <4 x i1> @test_fcmp_ueq(<4 x half> %a, <4 x half> %b) #0 { %1 = fcmp ueq <4 x half> %a, %b ret <4 x i1> %1 @@ -319,10 +319,10 @@ ; CHECK-DAG: fcvt ; CHECK-DAG: fcvt ; CHECK-DAG: fcvt -; CHECK-DAG: csel {{.*}}, wzr, hi -; CHECK-DAG: csel {{.*}}, wzr, hi -; CHECK-DAG: csel {{.*}}, wzr, hi -; CHECK-DAG: csel {{.*}}, wzr, hi +; CHECK-DAG: csetm {{.*}}, hi +; CHECK-DAG: csetm {{.*}}, hi +; CHECK-DAG: csetm {{.*}}, hi +; CHECK-DAG: csetm {{.*}}, hi define <4 x i1> @test_fcmp_ugt(<4 x half> %a, <4 x half> %b) #0 { %1 = fcmp ugt <4 x half> %a, %b ret <4 x i1> %1 @@ -338,10 +338,10 @@ ; CHECK-DAG: fcvt ; CHECK-DAG: fcvt ; CHECK-DAG: fcvt -; CHECK-DAG: csel {{.*}}, wzr, pl -; CHECK-DAG: csel {{.*}}, wzr, pl -; CHECK-DAG: csel {{.*}}, wzr, pl -; CHECK-DAG: csel {{.*}}, wzr, pl +; CHECK-DAG: csetm {{.*}}, pl +; CHECK-DAG: csetm {{.*}}, pl +; CHECK-DAG: csetm {{.*}}, pl +; CHECK-DAG: csetm {{.*}}, pl define <4 x i1> @test_fcmp_uge(<4 x half> %a, <4 x half> %b) #0 { %1 = fcmp uge <4 x half> %a, %b ret <4 x i1> %1 @@ -357,10 +357,10 @@ ; CHECK-DAG: fcvt ; CHECK-DAG: fcvt ; CHECK-DAG: fcvt -; CHECK-DAG: csel {{.*}}, wzr, lt -; CHECK-DAG: csel {{.*}}, wzr, lt -; CHECK-DAG: csel {{.*}}, wzr, lt -; CHECK-DAG: csel {{.*}}, wzr, lt +; CHECK-DAG: csetm {{.*}}, lt +; CHECK-DAG: csetm {{.*}}, lt +; CHECK-DAG: csetm {{.*}}, lt +; CHECK-DAG: csetm {{.*}}, lt define <4 x i1> @test_fcmp_ult(<4 x half> %a, <4 x half> %b) #0 { %1 = fcmp ult <4 x half> %a, %b ret <4 x i1> %1 @@ -376,10 +376,10 @@ ; CHECK-DAG: fcvt ; CHECK-DAG: fcvt ; CHECK-DAG: fcvt -; CHECK-DAG: csel {{.*}}, wzr, le -; CHECK-DAG: csel {{.*}}, wzr, le -; CHECK-DAG: csel {{.*}}, wzr, le -; CHECK-DAG: csel {{.*}}, wzr, le +; CHECK-DAG: csetm {{.*}}, le +; CHECK-DAG: csetm {{.*}}, le +; CHECK-DAG: csetm {{.*}}, le +; CHECK-DAG: csetm {{.*}}, le define <4 x i1> @test_fcmp_ule(<4 x half> %a, <4 x half> %b) #0 { %1 = fcmp ule <4 x half> %a, %b ret <4 x i1> %1 @@ -395,10 +395,10 @@ ; CHECK-DAG: fcvt ; CHECK-DAG: fcvt ; CHECK-DAG: fcvt -; CHECK-DAG: csel {{.*}}, wzr, vs -; CHECK-DAG: csel {{.*}}, wzr, vs -; CHECK-DAG: csel {{.*}}, wzr, vs -; CHECK-DAG: csel {{.*}}, wzr, vs +; CHECK-DAG: csetm {{.*}}, vs +; CHECK-DAG: csetm {{.*}}, vs +; CHECK-DAG: csetm {{.*}}, vs +; CHECK-DAG: csetm {{.*}}, vs define <4 x i1> @test_fcmp_uno(<4 x half> %a, <4 x half> %b) #0 { %1 = fcmp uno <4 x half> %a, %b ret <4 x i1> %1 @@ -414,14 +414,15 @@ ; CHECK-DAG: fcvt ; CHECK-DAG: fcvt ; CHECK-DAG: fcvt -; CHECK-DAG: csel {{.*}}, wzr, mi -; CHECK-DAG: csel {{.*}}, wzr, mi -; CHECK-DAG: csel {{.*}}, wzr, mi -; CHECK-DAG: csel {{.*}}, wzr, mi -; CHECK-DAG: csel {{.*}}, gt -; CHECK-DAG: csel {{.*}}, gt -; CHECK-DAG: csel {{.*}}, gt -; CHECK-DAG: csel {{.*}}, gt +; CHECK-DAG: csetm [[REG1:w[0-9]+]], mi +; CHECK-DAG: csetm [[REG2:w[0-9]+]], mi +; CHECK-DAG: csetm [[REG3:w[0-9]+]], mi +; CHECK-DAG: csetm [[REG4:w[0-9]+]], mi +; CHECK-DAG: csinv {{.*}}, [[REG1]], wzr, le +; CHECK-DAG: csinv {{.*}}, [[REG2]], wzr, le +; CHECK-DAG: csinv {{.*}}, [[REG3]], wzr, le +; CHECK-DAG: csinv {{.*}}, [[REG4]], wzr, le + define <4 x i1> @test_fcmp_one(<4 x half> %a, <4 x half> %b) #0 { %1 = fcmp one <4 x half> %a, %b ret <4 x i1> %1 @@ -437,10 +438,10 @@ ; CHECK-DAG: fcvt ; CHECK-DAG: fcvt ; CHECK-DAG: fcvt -; CHECK-DAG: csel {{.*}}, wzr, eq -; CHECK-DAG: csel {{.*}}, wzr, eq -; CHECK-DAG: csel {{.*}}, wzr, eq -; CHECK-DAG: csel {{.*}}, wzr, eq +; CHECK-DAG: csetm {{.*}}, eq +; CHECK-DAG: csetm {{.*}}, eq +; CHECK-DAG: csetm {{.*}}, eq +; CHECK-DAG: csetm {{.*}}, eq define <4 x i1> @test_fcmp_oeq(<4 x half> %a, <4 x half> %b) #0 { %1 = fcmp oeq <4 x half> %a, %b ret <4 x i1> %1 @@ -456,10 +457,10 @@ ; CHECK-DAG: fcvt ; CHECK-DAG: fcvt ; CHECK-DAG: fcvt -; CHECK-DAG: csel {{.*}}, wzr, gt -; CHECK-DAG: csel {{.*}}, wzr, gt -; CHECK-DAG: csel {{.*}}, wzr, gt -; CHECK-DAG: csel {{.*}}, wzr, gt +; CHECK-DAG: csetm {{.*}}, gt +; CHECK-DAG: csetm {{.*}}, gt +; CHECK-DAG: csetm {{.*}}, gt +; CHECK-DAG: csetm {{.*}}, gt define <4 x i1> @test_fcmp_ogt(<4 x half> %a, <4 x half> %b) #0 { %1 = fcmp ogt <4 x half> %a, %b ret <4 x i1> %1 @@ -475,10 +476,10 @@ ; CHECK-DAG: fcvt ; CHECK-DAG: fcvt ; CHECK-DAG: fcvt -; CHECK-DAG: csel {{.*}}, wzr, ge -; CHECK-DAG: csel {{.*}}, wzr, ge -; CHECK-DAG: csel {{.*}}, wzr, ge -; CHECK-DAG: csel {{.*}}, wzr, ge +; CHECK-DAG: csetm {{.*}}, ge +; CHECK-DAG: csetm {{.*}}, ge +; CHECK-DAG: csetm {{.*}}, ge +; CHECK-DAG: csetm {{.*}}, ge define <4 x i1> @test_fcmp_oge(<4 x half> %a, <4 x half> %b) #0 { %1 = fcmp oge <4 x half> %a, %b ret <4 x i1> %1 @@ -494,10 +495,10 @@ ; CHECK-DAG: fcvt ; CHECK-DAG: fcvt ; CHECK-DAG: fcvt -; CHECK-DAG: csel {{.*}}, wzr, mi -; CHECK-DAG: csel {{.*}}, wzr, mi -; CHECK-DAG: csel {{.*}}, wzr, mi -; CHECK-DAG: csel {{.*}}, wzr, mi +; CHECK-DAG: csetm {{.*}}, mi +; CHECK-DAG: csetm {{.*}}, mi +; CHECK-DAG: csetm {{.*}}, mi +; CHECK-DAG: csetm {{.*}}, mi define <4 x i1> @test_fcmp_olt(<4 x half> %a, <4 x half> %b) #0 { %1 = fcmp olt <4 x half> %a, %b ret <4 x i1> %1 @@ -513,10 +514,10 @@ ; CHECK-DAG: fcvt ; CHECK-DAG: fcvt ; CHECK-DAG: fcvt -; CHECK-DAG: csel {{.*}}, wzr, ls -; CHECK-DAG: csel {{.*}}, wzr, ls -; CHECK-DAG: csel {{.*}}, wzr, ls -; CHECK-DAG: csel {{.*}}, wzr, ls +; CHECK-DAG: csetm {{.*}}, ls +; CHECK-DAG: csetm {{.*}}, ls +; CHECK-DAG: csetm {{.*}}, ls +; CHECK-DAG: csetm {{.*}}, ls define <4 x i1> @test_fcmp_ole(<4 x half> %a, <4 x half> %b) #0 { %1 = fcmp ole <4 x half> %a, %b ret <4 x i1> %1 @@ -532,10 +533,10 @@ ; CHECK-DAG: fcvt ; CHECK-DAG: fcvt ; CHECK-DAG: fcvt -; CHECK-DAG: csel {{.*}}, wzr, vc -; CHECK-DAG: csel {{.*}}, wzr, vc -; CHECK-DAG: csel {{.*}}, wzr, vc -; CHECK-DAG: csel {{.*}}, wzr, vc +; CHECK-DAG: csetm {{.*}}, vc +; CHECK-DAG: csetm {{.*}}, vc +; CHECK-DAG: csetm {{.*}}, vc +; CHECK-DAG: csetm {{.*}}, vc define <4 x i1> @test_fcmp_ord(<4 x half> %a, <4 x half> %b) #0 { %1 = fcmp ord <4 x half> %a, %b ret <4 x i1> %1