[CGP] Limit converting phi types to simple loads and stores
authorDavid Green <david.green@arm.com>
Mon, 14 Sep 2020 11:08:34 +0000 (12:08 +0100)
committerDavid Green <david.green@arm.com>
Mon, 14 Sep 2020 11:08:34 +0000 (12:08 +0100)
Instcombine limits converting phi types to simple loads and stores. This
does the same in codegenprepare, not processing phis that are not
simple.

Note that volatile loads/store ISel will happily convert between float
and int. Atomics are more likely to always be integer. This just keeps
things simple and doesn't process either.

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

llvm/lib/CodeGen/CodeGenPrepare.cpp
llvm/test/CodeGen/AArch64/convertphitype.ll

index bb0bad7..45feeae 100644 (file)
@@ -5831,6 +5831,8 @@ bool CodeGenPrepare::optimizePhiType(
             Worklist.push_back(OpPhi);
           }
         } else if (auto *OpLoad = dyn_cast<LoadInst>(V)) {
+          if (!OpLoad->isSimple())
+            return false;
           if (!Defs.count(OpLoad)) {
             Defs.insert(OpLoad);
             Worklist.push_back(OpLoad);
@@ -5868,7 +5870,7 @@ bool CodeGenPrepare::optimizePhiType(
           Worklist.push_back(OpPhi);
         }
       } else if (auto *OpStore = dyn_cast<StoreInst>(V)) {
-        if (OpStore->getOperand(0) != II)
+        if (!OpStore->isSimple() || OpStore->getOperand(0) != II)
           return false;
         Uses.insert(OpStore);
       } else if (auto *OpBC = dyn_cast<BitCastInst>(V)) {
index 2e3530d..bc858aa 100644 (file)
@@ -677,3 +677,203 @@ end:
   %b = bitcast i32 %phi to float
   ret float %b
 }
+
+define float @convphi_volatile(i32 *%s, i32 *%d, i32 %n) {
+; CHECK-LABEL: @convphi_volatile(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CMP15:%.*]] = icmp sgt i32 [[N:%.*]], 0
+; CHECK-NEXT:    br i1 [[CMP15]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; CHECK:       then:
+; CHECK-NEXT:    [[LS:%.*]] = load volatile i32, i32* [[S:%.*]], align 4
+; CHECK-NEXT:    br label [[END:%.*]]
+; CHECK:       else:
+; CHECK-NEXT:    [[LD:%.*]] = load i32, i32* [[D:%.*]], align 4
+; CHECK-NEXT:    br label [[END]]
+; CHECK:       end:
+; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ [[LS]], [[THEN]] ], [ [[LD]], [[ELSE]] ]
+; CHECK-NEXT:    [[B:%.*]] = bitcast i32 [[PHI]] to float
+; CHECK-NEXT:    ret float [[B]]
+;
+; DEBUG-LABEL: @convphi_volatile(
+; DEBUG-NEXT:  entry:
+; DEBUG-NEXT:    [[CMP15:%.*]] = icmp sgt i32 [[N:%.*]], 0, !dbg !358
+; DEBUG-NEXT:    call void @llvm.dbg.value(metadata i1 [[CMP15]], metadata !353, metadata !DIExpression()), !dbg !358
+; DEBUG-NEXT:    br i1 [[CMP15]], label [[THEN:%.*]], label [[ELSE:%.*]], !dbg !359
+; DEBUG:       then:
+; DEBUG-NEXT:    [[LS:%.*]] = load volatile i32, i32* [[S:%.*]], align 4, !dbg !360
+; DEBUG-NEXT:    call void @llvm.dbg.value(metadata i32 [[LS]], metadata !354, metadata !DIExpression()), !dbg !360
+; DEBUG-NEXT:    br label [[END:%.*]], !dbg !361
+; DEBUG:       else:
+; DEBUG-NEXT:    [[LD:%.*]] = load i32, i32* [[D:%.*]], align 4, !dbg !362
+; DEBUG-NEXT:    call void @llvm.dbg.value(metadata i32 [[LD]], metadata !355, metadata !DIExpression()), !dbg !362
+; DEBUG-NEXT:    br label [[END]], !dbg !363
+; DEBUG:       end:
+; DEBUG-NEXT:    [[PHI:%.*]] = phi i32 [ [[LS]], [[THEN]] ], [ [[LD]], [[ELSE]] ], !dbg !364
+; DEBUG-NEXT:    call void @llvm.dbg.value(metadata i32 [[PHI]], metadata !356, metadata !DIExpression()), !dbg !364
+; DEBUG-NEXT:    [[B:%.*]] = bitcast i32 [[PHI]] to float, !dbg !365
+; DEBUG-NEXT:    call void @llvm.dbg.value(metadata float [[B]], metadata !357, metadata !DIExpression()), !dbg !365
+; DEBUG-NEXT:    ret float [[B]], !dbg !366
+;
+entry:
+  %cmp15 = icmp sgt i32 %n, 0
+  br i1 %cmp15, label %then, label %else
+
+then:
+  %ls = load volatile i32, i32* %s, align 4
+  br label %end
+
+else:
+  %ld = load i32, i32* %d, align 4
+  br label %end
+
+end:
+  %phi = phi i32 [ %ls, %then ], [ %ld, %else ]
+  %b = bitcast i32 %phi to float
+  ret float %b
+}
+
+define void @convphi_volatile2(i32 *%s, i32 *%d, i32 %n, float %f) {
+; CHECK-LABEL: @convphi_volatile2(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CMP15:%.*]] = icmp sgt i32 [[N:%.*]], 0
+; CHECK-NEXT:    [[FB:%.*]] = bitcast float [[F:%.*]] to i32
+; CHECK-NEXT:    br i1 [[CMP15]], label [[THEN:%.*]], label [[END:%.*]]
+; CHECK:       then:
+; CHECK-NEXT:    [[LS:%.*]] = load i32, i32* [[S:%.*]], align 4
+; CHECK-NEXT:    br label [[END]]
+; CHECK:       end:
+; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ [[LS]], [[THEN]] ], [ [[FB]], [[ENTRY:%.*]] ]
+; CHECK-NEXT:    store volatile i32 [[PHI]], i32* [[D:%.*]], align 4
+; CHECK-NEXT:    ret void
+;
+; DEBUG-LABEL: @convphi_volatile2(
+; DEBUG-NEXT:  entry:
+; DEBUG-NEXT:    [[CMP15:%.*]] = icmp sgt i32 [[N:%.*]], 0, !dbg !373
+; DEBUG-NEXT:    call void @llvm.dbg.value(metadata i1 [[CMP15]], metadata !369, metadata !DIExpression()), !dbg !373
+; DEBUG-NEXT:    [[FB:%.*]] = bitcast float [[F:%.*]] to i32, !dbg !374
+; DEBUG-NEXT:    call void @llvm.dbg.value(metadata i32 [[FB]], metadata !370, metadata !DIExpression()), !dbg !374
+; DEBUG-NEXT:    br i1 [[CMP15]], label [[THEN:%.*]], label [[END:%.*]], !dbg !375
+; DEBUG:       then:
+; DEBUG-NEXT:    [[LS:%.*]] = load i32, i32* [[S:%.*]], align 4, !dbg !376
+; DEBUG-NEXT:    call void @llvm.dbg.value(metadata i32 [[LS]], metadata !371, metadata !DIExpression()), !dbg !376
+; DEBUG-NEXT:    br label [[END]], !dbg !377
+; DEBUG:       end:
+; DEBUG-NEXT:    [[PHI:%.*]] = phi i32 [ [[LS]], [[THEN]] ], [ [[FB]], [[ENTRY:%.*]] ], !dbg !378
+; DEBUG-NEXT:    call void @llvm.dbg.value(metadata i32 [[PHI]], metadata !372, metadata !DIExpression()), !dbg !378
+; DEBUG-NEXT:    store volatile i32 [[PHI]], i32* [[D:%.*]], align 4, !dbg !379
+; DEBUG-NEXT:    ret void, !dbg !380
+;
+entry:
+  %cmp15 = icmp sgt i32 %n, 0
+  %fb = bitcast float %f to i32
+  br i1 %cmp15, label %then, label %end
+
+then:
+  %ls = load i32, i32* %s, align 4
+  br label %end
+
+end:
+  %phi = phi i32 [ %ls, %then ], [ %fb, %entry ]
+  store volatile i32 %phi, i32 *%d
+  ret void
+}
+
+define float @convphi_atomic(i32 *%s, i32 *%d, i32 %n) {
+; CHECK-LABEL: @convphi_atomic(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CMP15:%.*]] = icmp sgt i32 [[N:%.*]], 0
+; CHECK-NEXT:    br i1 [[CMP15]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; CHECK:       then:
+; CHECK-NEXT:    [[LS:%.*]] = load atomic i32, i32* [[S:%.*]] acquire, align 4
+; CHECK-NEXT:    br label [[END:%.*]]
+; CHECK:       else:
+; CHECK-NEXT:    [[LD:%.*]] = load i32, i32* [[D:%.*]], align 4
+; CHECK-NEXT:    br label [[END]]
+; CHECK:       end:
+; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ [[LS]], [[THEN]] ], [ [[LD]], [[ELSE]] ]
+; CHECK-NEXT:    [[B:%.*]] = bitcast i32 [[PHI]] to float
+; CHECK-NEXT:    ret float [[B]]
+;
+; DEBUG-LABEL: @convphi_atomic(
+; DEBUG-NEXT:  entry:
+; DEBUG-NEXT:    [[CMP15:%.*]] = icmp sgt i32 [[N:%.*]], 0, !dbg !388
+; DEBUG-NEXT:    call void @llvm.dbg.value(metadata i1 [[CMP15]], metadata !383, metadata !DIExpression()), !dbg !388
+; DEBUG-NEXT:    br i1 [[CMP15]], label [[THEN:%.*]], label [[ELSE:%.*]], !dbg !389
+; DEBUG:       then:
+; DEBUG-NEXT:    [[LS:%.*]] = load atomic i32, i32* [[S:%.*]] acquire, align 4, !dbg !390
+; DEBUG-NEXT:    call void @llvm.dbg.value(metadata i32 [[LS]], metadata !384, metadata !DIExpression()), !dbg !390
+; DEBUG-NEXT:    br label [[END:%.*]], !dbg !391
+; DEBUG:       else:
+; DEBUG-NEXT:    [[LD:%.*]] = load i32, i32* [[D:%.*]], align 4, !dbg !392
+; DEBUG-NEXT:    call void @llvm.dbg.value(metadata i32 [[LD]], metadata !385, metadata !DIExpression()), !dbg !392
+; DEBUG-NEXT:    br label [[END]], !dbg !393
+; DEBUG:       end:
+; DEBUG-NEXT:    [[PHI:%.*]] = phi i32 [ [[LS]], [[THEN]] ], [ [[LD]], [[ELSE]] ], !dbg !394
+; DEBUG-NEXT:    call void @llvm.dbg.value(metadata i32 [[PHI]], metadata !386, metadata !DIExpression()), !dbg !394
+; DEBUG-NEXT:    [[B:%.*]] = bitcast i32 [[PHI]] to float, !dbg !395
+; DEBUG-NEXT:    call void @llvm.dbg.value(metadata float [[B]], metadata !387, metadata !DIExpression()), !dbg !395
+; DEBUG-NEXT:    ret float [[B]], !dbg !396
+;
+entry:
+  %cmp15 = icmp sgt i32 %n, 0
+  br i1 %cmp15, label %then, label %else
+
+then:
+  %ls = load atomic i32, i32* %s acquire, align 4
+  br label %end
+
+else:
+  %ld = load i32, i32* %d, align 4
+  br label %end
+
+end:
+  %phi = phi i32 [ %ls, %then ], [ %ld, %else ]
+  %b = bitcast i32 %phi to float
+  ret float %b
+}
+
+define void @convphi_atomic2(i32 *%s, i32 *%d, i32 %n, float %f) {
+; CHECK-LABEL: @convphi_atomic2(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CMP15:%.*]] = icmp sgt i32 [[N:%.*]], 0
+; CHECK-NEXT:    [[FB:%.*]] = bitcast float [[F:%.*]] to i32
+; CHECK-NEXT:    br i1 [[CMP15]], label [[THEN:%.*]], label [[END:%.*]]
+; CHECK:       then:
+; CHECK-NEXT:    [[LS:%.*]] = load i32, i32* [[S:%.*]], align 4
+; CHECK-NEXT:    br label [[END]]
+; CHECK:       end:
+; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ [[LS]], [[THEN]] ], [ [[FB]], [[ENTRY:%.*]] ]
+; CHECK-NEXT:    store atomic i32 [[PHI]], i32* [[D:%.*]] release, align 4
+; CHECK-NEXT:    ret void
+;
+; DEBUG-LABEL: @convphi_atomic2(
+; DEBUG-NEXT:  entry:
+; DEBUG-NEXT:    [[CMP15:%.*]] = icmp sgt i32 [[N:%.*]], 0, !dbg !403
+; DEBUG-NEXT:    call void @llvm.dbg.value(metadata i1 [[CMP15]], metadata !399, metadata !DIExpression()), !dbg !403
+; DEBUG-NEXT:    [[FB:%.*]] = bitcast float [[F:%.*]] to i32, !dbg !404
+; DEBUG-NEXT:    call void @llvm.dbg.value(metadata i32 [[FB]], metadata !400, metadata !DIExpression()), !dbg !404
+; DEBUG-NEXT:    br i1 [[CMP15]], label [[THEN:%.*]], label [[END:%.*]], !dbg !405
+; DEBUG:       then:
+; DEBUG-NEXT:    [[LS:%.*]] = load i32, i32* [[S:%.*]], align 4, !dbg !406
+; DEBUG-NEXT:    call void @llvm.dbg.value(metadata i32 [[LS]], metadata !401, metadata !DIExpression()), !dbg !406
+; DEBUG-NEXT:    br label [[END]], !dbg !407
+; DEBUG:       end:
+; DEBUG-NEXT:    [[PHI:%.*]] = phi i32 [ [[LS]], [[THEN]] ], [ [[FB]], [[ENTRY:%.*]] ], !dbg !408
+; DEBUG-NEXT:    call void @llvm.dbg.value(metadata i32 [[PHI]], metadata !402, metadata !DIExpression()), !dbg !408
+; DEBUG-NEXT:    store atomic i32 [[PHI]], i32* [[D:%.*]] release, align 4, !dbg !409
+; DEBUG-NEXT:    ret void, !dbg !410
+;
+entry:
+  %cmp15 = icmp sgt i32 %n, 0
+  %fb = bitcast float %f to i32
+  br i1 %cmp15, label %then, label %end
+
+then:
+  %ls = load i32, i32* %s, align 4
+  br label %end
+
+end:
+  %phi = phi i32 [ %ls, %then ], [ %fb, %entry ]
+  store atomic i32 %phi, i32 *%d release, align 4
+  ret void
+}