[PowerPC] Use rldicr instruction for AND with an immediate if possible

Emit clrrdi (extended mnemonic for rldicr) for AND-ing with masks that
clear bits from the right hand size.

Committing on behalf of Hiroshi Inoue.

Differential Revision: https://reviews.llvm.org/D29388

llvm-svn: 296143
diff --git a/llvm/test/CodeGen/PowerPC/fp128-bitcast-after-operation.ll b/llvm/test/CodeGen/PowerPC/fp128-bitcast-after-operation.ll
index 37120a5..c76c7b0 100644
--- a/llvm/test/CodeGen/PowerPC/fp128-bitcast-after-operation.ll
+++ b/llvm/test/CodeGen/PowerPC/fp128-bitcast-after-operation.ll
@@ -11,11 +11,9 @@
 ; PPC64-DAG: stxsdx 1, 0, [[ADDR_LO:[0-9]+]]
 ; PPC64-DAG: addi [[ADDR_HI]], [[SP:[0-9]+]], [[OFFSET_HI:-?[0-9]+]]
 ; PPC64-DAG: addi [[ADDR_LO]], [[SP]], [[OFFSET_LO:-?[0-9]+]]
-; PPC64-DAG: li [[MASK_REG:[0-9]+]], 1
-; PPC64: sldi [[MASK_REG]], [[MASK_REG]], 63
 ; PPC64-DAG: ld [[HI:[0-9]+]], [[OFFSET_LO]]([[SP]])
 ; PPC64-DAG: ld [[LO:[0-9]+]], [[OFFSET_HI]]([[SP]])
-; PPC64: and [[FLIP_BIT:[0-9]+]], [[HI]], [[MASK_REG]]
+; PPC64-DAG: rldicr [[FLIP_BIT:[0-9]+]], [[HI]], 0, 0
 ; PPC64-DAG: xor 3, [[HI]], [[FLIP_BIT]]
 ; PPC64-DAG: xor 4, [[LO]], [[FLIP_BIT]]
 ; PPC64: blr
@@ -23,9 +21,7 @@
 ; PPC64-P8-LABEL: test_abs:
 ; PPC64-P8-DAG: mfvsrd [[LO:[0-9]+]], 2
 ; PPC64-P8-DAG: mfvsrd [[HI:[0-9]+]], 1
-; PPC64-P8-DAG: li [[MASK_REG:[0-9]+]], 1
-; PPC64-P8-DAG: sldi [[SHIFT_REG:[0-9]+]], [[MASK_REG]], 63
-; PPC64-P8: and [[FLIP_BIT:[0-9]+]], [[HI]], [[SHIFT_REG]]
+; PPC64-P8-DAG: rldicr [[FLIP_BIT:[0-9]+]], [[HI]], 0, 0
 ; PPC64-P8-DAG: xor 3, [[HI]], [[FLIP_BIT]]
 ; PPC64-P8-DAG: xor 4, [[LO]], [[FLIP_BIT]]
 ; PPC64-P8: blr
@@ -66,7 +62,7 @@
 ; PPC64-P8-DAG: mfvsrd [[LO:[0-9]+]], 2
 ; PPC64-P8-DAG: mfvsrd [[HI:[0-9]+]], 1
 ; PPC64-P8-DAG: li [[IMM1:[0-9]+]], 1
-; PPC64-P8-DAG: sldi [[FLIP_BIT]], [[IMM1]], 63
+; PPC64-P8-DAG: sldi [[FLIP_BIT:[0-9]+]], [[IMM1]], 63
 ; PPC64-P8-NOT: BARRIER
 ; PPC64-P8-DAG: xor 3, [[HI]], [[FLIP_BIT]]
 ; PPC64-P8-DAG: xor 4, [[LO]], [[FLIP_BIT]]
@@ -93,29 +89,25 @@
 ; PPC64-LABEL: test_copysign:
 ; PPC64-DAG: stxsdx 1, 0, [[ADDR_REG:[0-9]+]]
 ; PPC64-DAG: addi [[ADDR_REG]], 1, [[OFFSET:-?[0-9]+]]
-; PPC64-DAG: li [[SIGN:[0-9]+]], 1
-; PPC64-DAG: sldi [[SIGN]], [[SIGN]], 63
 ; PPC64-DAG: li [[HI_TMP:[0-9]+]], 16399
 ; PPC64-DAG: sldi [[CST_HI:[0-9]+]], [[HI_TMP]], 48
 ; PPC64-DAG: li [[LO_TMP:[0-9]+]], 3019
 ; PPC64-DAG: sldi [[CST_LO:[0-9]+]], [[LO_TMP]], 52
 ; PPC64-NOT: BARRIER
 ; PPC64-DAG: ld [[X_HI:[0-9]+]], [[OFFSET]](1)
-; PPC64-DAG: and [[NEW_HI_TMP:[0-9]+]], [[X_HI]], [[SIGN]]
+; PPC64-DAG: rldicr [[NEW_HI_TMP:[0-9]+]], [[X_HI]], 0, 0
 ; PPC64-DAG: or 3, [[NEW_HI_TMP]], [[CST_HI]]
-; PPC64-DAG: xor 4, [[SIGN]], [[CST_LO]]
+; PPC64-DAG: xor 4, [[NEW_HI_TMP]], [[CST_LO]]
 ; PPC64: blr
 
 ; PPC64-P8-LABEL: test_copysign:
 ; PPC64-P8-DAG: mfvsrd [[X_HI:[0-9]+]], 1
-; PPC64-P8-DAG: li [[SIGN:[0-9]+]], 1
-; PPC64-P8-DAG: sldi [[SIGN]], [[SIGN]], 63
 ; PPC64-P8-DAG: li [[HI_TMP:[0-9]+]], 16399
 ; PPC64-P8-DAG: sldi [[CST_HI:[0-9]+]], [[HI_TMP]], 48
 ; PPC64-P8-DAG: li [[LO_TMP:[0-9]+]], 3019
 ; PPC64-P8-DAG: sldi [[CST_LO:[0-9]+]], [[LO_TMP]], 52
 ; PPC64-P8-NOT: BARRIER
-; PPC64-P8-DAG: and [[NEW_HI_TMP:[0-9]+]], [[X_HI]], [[SIGN]]
+; PPC64-P8-DAG: rldicr [[NEW_HI_TMP:[0-9]+]], [[X_HI]], 0, 0
 ; PPC64-P8-DAG: or 3, [[NEW_HI_TMP]], [[CST_HI]]
 ; PPC64-P8-DAG: xor 4, [[NEW_HI_TMP]], [[CST_LO]]
 ; PPC64-P8: blr
diff --git a/llvm/test/CodeGen/PowerPC/i64_fp_round.ll b/llvm/test/CodeGen/PowerPC/i64_fp_round.ll
index 5e959f7..9fe7a3b 100644
--- a/llvm/test/CodeGen/PowerPC/i64_fp_round.ll
+++ b/llvm/test/CodeGen/PowerPC/i64_fp_round.ll
@@ -19,11 +19,14 @@
 ; CHECK: addi [[REG2:[0-9]+]], [[REG1]], 1
 ; CHECK: cmpldi [[REG2]], 1
 ; CHECK: isel [[REG3:[0-9]+]], {{[0-9]+}}, 3, 1
+; CHECK-NO-ISEL: rldicr [[REG2:[0-9]+]], {{[0-9]+}}, 0, 52
 ; CHECK-NO-ISEL: bc 12, 1, [[TRUE:.LBB[0-9]+]]
-; CHECK-NO-ISEL: ori 11, 3, 0
+; CHECK-NO-ISEL: ori [[REG3:[0-9]+]], 3, 0
 ; CHECK-NO-ISEL-NEXT: b [[SUCCESSOR:.LBB[0-9]+]]
 ; CHECK-NO-ISEL-NEXT: [[TRUE]]
-; CHECK-NO-ISEL-NEXT: addi 11, 4, 0
+; CHECK-NO-ISEL-NEXT: addi [[REG3]], [[REG2]], 0
+; CHECK-NO-ISEL-NEXT: [[SUCCESSOR]]
+; CHECK-NO-ISEL: std [[REG3]], -{{[0-9]+}}(1)
 ; CHECK: std [[REG3]], -{{[0-9]+}}(1)
 
 
diff --git a/llvm/test/CodeGen/PowerPC/srl-mask.ll b/llvm/test/CodeGen/PowerPC/srl-mask.ll
index e581eae..1a429b1 100644
--- a/llvm/test/CodeGen/PowerPC/srl-mask.ll
+++ b/llvm/test/CodeGen/PowerPC/srl-mask.ll
@@ -12,5 +12,16 @@
 ; CHECK: blr
 }
 
+; for AND with an immediate like (x & ~0xFFFF)
+; we should use rldicl instruction
+define i64 @bar(i64 %x) #0 {
+entry:
+; CHECK-LABEL: @bar
+  %a = and i64 %x, 18446744073709486080
+; CHECK: rldicr 3, 3, 0, 47
+  ret i64 %a
+; CHECK: blr
+}
+
 attributes #0 = { nounwind }