@@ -83,7 +83,7 @@ int inc0() {
8383// CHECK: %[[ATMP:.*]] = cir.const #cir.int<1> : !s32i
8484// CHECK: cir.store %[[ATMP]], %[[A]] : !s32i
8585// CHECK: %[[INPUT:.*]] = cir.load %[[A]]
86- // CHECK: %[[INCREMENTED:.*]] = cir.unary(inc, %[[INPUT]])
86+ // CHECK: %[[INCREMENTED:.*]] = cir.unary(inc, %[[INPUT]]) nsw
8787// CHECK: cir.store %[[INCREMENTED]], %[[A]]
8888// CHECK: %[[A_TO_OUTPUT:.*]] = cir.load %[[A]]
8989
@@ -111,8 +111,8 @@ int dec0() {
111111// CHECK: %[[ATMP:.*]] = cir.const #cir.int<1> : !s32i
112112// CHECK: cir.store %[[ATMP]], %[[A]] : !s32i
113113// CHECK: %[[INPUT:.*]] = cir.load %[[A]]
114- // CHECK: %[[INCREMENTED :.*]] = cir.unary(dec, %[[INPUT]])
115- // CHECK: cir.store %[[INCREMENTED ]], %[[A]]
114+ // CHECK: %[[DECREMENTED :.*]] = cir.unary(dec, %[[INPUT]]) nsw
115+ // CHECK: cir.store %[[DECREMENTED ]], %[[A]]
116116// CHECK: %[[A_TO_OUTPUT:.*]] = cir.load %[[A]]
117117
118118// LLVM: define i32 @dec0()
@@ -139,7 +139,7 @@ int inc1() {
139139// CHECK: %[[ATMP:.*]] = cir.const #cir.int<1> : !s32i
140140// CHECK: cir.store %[[ATMP]], %[[A]] : !s32i
141141// CHECK: %[[INPUT:.*]] = cir.load %[[A]]
142- // CHECK: %[[INCREMENTED:.*]] = cir.unary(inc, %[[INPUT]])
142+ // CHECK: %[[INCREMENTED:.*]] = cir.unary(inc, %[[INPUT]]) nsw
143143// CHECK: cir.store %[[INCREMENTED]], %[[A]]
144144// CHECK: %[[A_TO_OUTPUT:.*]] = cir.load %[[A]]
145145
@@ -167,8 +167,8 @@ int dec1() {
167167// CHECK: %[[ATMP:.*]] = cir.const #cir.int<1> : !s32i
168168// CHECK: cir.store %[[ATMP]], %[[A]] : !s32i
169169// CHECK: %[[INPUT:.*]] = cir.load %[[A]]
170- // CHECK: %[[INCREMENTED :.*]] = cir.unary(dec, %[[INPUT]])
171- // CHECK: cir.store %[[INCREMENTED ]], %[[A]]
170+ // CHECK: %[[DECREMENTED :.*]] = cir.unary(dec, %[[INPUT]]) nsw
171+ // CHECK: cir.store %[[DECREMENTED ]], %[[A]]
172172// CHECK: %[[A_TO_OUTPUT:.*]] = cir.load %[[A]]
173173
174174// LLVM: define i32 @dec1()
@@ -197,7 +197,7 @@ int inc2() {
197197// CHECK: %[[ATMP:.*]] = cir.const #cir.int<1> : !s32i
198198// CHECK: cir.store %[[ATMP]], %[[A]] : !s32i
199199// CHECK: %[[ATOB:.*]] = cir.load %[[A]]
200- // CHECK: %[[INCREMENTED:.*]] = cir.unary(inc, %[[ATOB]])
200+ // CHECK: %[[INCREMENTED:.*]] = cir.unary(inc, %[[ATOB]]) nsw
201201// CHECK: cir.store %[[INCREMENTED]], %[[A]]
202202// CHECK: cir.store %[[ATOB]], %[[B]]
203203// CHECK: %[[B_TO_OUTPUT:.*]] = cir.load %[[B]]
@@ -405,3 +405,22 @@ float fpPostInc2() {
405405// OGCG: store float %[[A_INC]], ptr %[[A]], align 4
406406// OGCG: store float %[[A_LOAD]], ptr %[[B]], align 4
407407// OGCG: %[[B_TO_OUTPUT:.*]] = load float, ptr %[[B]], align 4
408+
409+ void chars (char c) {
410+ // CHECK: cir.func @chars
411+
412+ int c1 = +c;
413+ // CHECK: %[[PROMO:.*]] = cir.cast(integral, %{{.+}} : !s8i), !s32i
414+ // CHECK: cir.unary(plus, %[[PROMO]]) : !s32i, !s32i
415+ int c2 = -c;
416+ // CHECK: %[[PROMO:.*]] = cir.cast(integral, %{{.+}} : !s8i), !s32i
417+ // CHECK: cir.unary(minus, %[[PROMO]]) nsw : !s32i, !s32i
418+
419+ // Chars can go through some integer promotion codegen paths even when not promoted.
420+ // These should not have nsw attributes because the intermediate promotion makes the
421+ // overflow defined behavior.
422+ ++c; // CHECK: cir.unary(inc, %{{.+}}) : !s8i, !s8i
423+ --c; // CHECK: cir.unary(dec, %{{.+}}) : !s8i, !s8i
424+ c++; // CHECK: cir.unary(inc, %{{.+}}) : !s8i, !s8i
425+ c--; // CHECK: cir.unary(dec, %{{.+}}) : !s8i, !s8i
426+ }
0 commit comments